コード例 #1
0
        /// <summary>
        /// Try to combine two of these guys
        /// </summary>
        /// <param name="statement"></param>
        /// <returns></returns>
        public override bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
            {
                throw new ArgumentNullException();
            }
            if (this == statement)
            {
                throw new ArgumentException("Can't comebine with self!");
            }

            var otherLoop = statement as StatementLoopOverGood;

            if (otherLoop == null)
            {
                return(false);
            }

            // Are they the same? _index is independent and we can alter it.
            if (otherLoop._indexIsGood.RawValue == _indexIsGood.RawValue &&
                otherLoop._indiciesToCheck.RawValue == _indiciesToCheck.RawValue)
            {
                if (!(opt.TryRenameVarialbeOneLevelUp(otherLoop._index.RawValue, _index)))
                {
                    return(false);
                }

                Combine(otherLoop, opt);
                return(true);
            }
            else
            {
                return(false);
            }
        }
コード例 #2
0
        /// <summary>
        /// Try to combine two assign statements. Since this will be for totally
        /// trivial cases, this should be "easy" - only when they are the same.
        /// </summary>
        /// <param name="statement"></param>
        /// <returns></returns>
        public bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
                throw new ArgumentNullException("statement");

            if (opt == null)
                throw new ArgumentNullException("opt");

            var otherAssign = statement as StatementAssign;
            if (otherAssign == null)
                return false;

            if (Expression.RawValue != otherAssign.Expression.RawValue)
                return false;

            // If the statements are identical, then we can combine by default without having to do any
            // further work.

            if (otherAssign.ResultVariable.RawValue == ResultVariable.RawValue)
                return true;

            // If we have declared, then we are sole owner - so we can force the change. Otherwise, we
            // need to let the infrastructure figure out where the declared is and change it from there.

            return opt.TryRenameVarialbeOneLevelUp(otherAssign.ResultVariable.RawValue, ResultVariable);
        }
コード例 #3
0
 public bool TryCombineStatement(IStatement statement, ICodeOptimizationService optimize)
 {
     var otherRtn = statement as StatementReturn;
     if (otherRtn == null)
         return false;
     return otherRtn._rtnValue.RawValue == _rtnValue.RawValue;
 }
コード例 #4
0
        /// <summary>
        /// See if we can combine statements
        /// </summary>
        /// <param name="statement"></param>
        /// <param name="opt"></param>
        /// <returns></returns>
        public override bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
            {
                throw new ArgumentNullException("statement");
            }

            var other = statement as StatementLoopOverGroupItems;

            if (other == null)
            {
                return(false);
            }

            if (_groupArray.RawValue != other._groupArray.RawValue)
            {
                return(false);
            }

            // We declare counter explicitly in the loop above - so we need to force the rename below rather
            // that rely on declared parameters.
            other.RenameVariable(other._counter.RawValue, _counter.RawValue);

            Combine(other, opt);
            return(true);
        }
コード例 #5
0
        /// <summary>
        /// Attempt to combine two record statements. We are a bit different, we have
        /// an object we depend on - which is record... and that has to be the same. The
        /// other one we need to propagate.
        /// </summary>
        /// <param name="statement"></param>
        /// <returns></returns>
        public bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
            {
                throw new ArgumentException("statement");
            }

            if (opt == null)
            {
                throw new ArgumentNullException("opt");
            }

            var asRecord = statement as StatementRecordIndicies;

            if (asRecord == null)
            {
                return(false);
            }

            if (_intToRecord.RawValue != asRecord._intToRecord.RawValue)
            {
                return(false);
            }

            //
            // Since int to record is the same, we do a rename and move on!
            //

            return(opt.TryRenameVarialbeOneLevelUp(asRecord._storageArray.RawValue, _storageArray));
        }
コード例 #6
0
        /// <summary>
        /// Can we combine? Yes, if and only if the same guy and same variables!
        /// </summary>
        /// <param name="statement"></param>
        /// <param name="optimize"></param>
        /// <returns></returns>
        public bool TryCombineStatement(IStatement statement, ICodeOptimizationService optimize)
        {
            if (statement.GetType() != typeof(StatementRecordPairValues))
            {
                return(false);
            }
            var other = statement as StatementRecordPairValues;

            if (other._index.RawValue != _index.RawValue)
            {
                return(false);
            }

            var isTheSame = _savers.Zip(other._savers, (f, s) => f.indexValue.RawValue == s.indexValue.RawValue && f.mapRecord.Type == s.mapRecord.Type).All(b => b);

            if (!isTheSame)
            {
                return(false);
            }

            // Now we can do them all.
            foreach (var saver in _savers.Zip(other._savers, (f, s) => Tuple.Create(f, s)))
            {
                optimize.TryRenameVarialbeOneLevelUp(saver.Item2.mapRecord.RawValue, saver.Item1.mapRecord);
            }

            return(true);
        }
コード例 #7
0
        /// <summary>
        /// If we are the same, then combine!
        /// </summary>
        /// <param name="statement"></param>
        /// <param name="opt"></param>
        /// <returns></returns>
        public override bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
            {
                throw new ArgumentNullException("statement");
            }

            var other = statement as StatementLoopOverGroups;

            if (other == null)
            {
                return(false);
            }

            if (_mapOfGroups.RawValue != other._mapOfGroups.RawValue)
            {
                return(false);
            }

            // We declare group index by hand, so we have to do the renaming by hand here too.
            other.RenameVariable(other._groupIndex.RawValue, _groupIndex.RawValue);

            Combine(other, opt);
            return(true);
        }
コード例 #8
0
        /// <summary>
        /// We can combine these two statements iff the array record we are looping
        /// over is the same. Rename the index after that!
        /// </summary>
        /// <param name="statement"></param>
        /// <returns></returns>
        public override bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
            {
                throw new ArgumentNullException("statement");
            }

            var otherPairLoop = statement as StatementPairLoop;

            if (otherPairLoop == null)
            {
                return(false);
            }

            if (otherPairLoop.arrayRecord.RawValue != arrayRecord.RawValue)
            {
                return(false);
            }

            // Just make sure the index guys are renamed!

            otherPairLoop.RenameVariable(otherPairLoop.index1.RawValue, index1.RawValue);
            otherPairLoop.RenameVariable(otherPairLoop.index2.RawValue, index2.RawValue);

            // Now, combine them!

            Combine(otherPairLoop, opt);

            return(true);
        }
コード例 #9
0
        /// <summary>
        /// We can only combine if everything is the same!
        /// </summary>
        /// <param name="statement"></param>
        /// <param name="opt"></param>
        /// <returns></returns>
        public bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
            {
                throw new ArgumentNullException("statement");
            }

            var other = statement as StatementTestLoopPairwise;

            if (other == null)
            {
                return(false);
            }

            if (_whatIsGood.ParameterName != other._whatIsGood.ParameterName ||
                _test.RawValue != _test.RawValue)
            {
                return(false);
            }

            //
            // Combining - nothing to do here.
            //

            return(true);
        }
コード例 #10
0
        /// <summary>
        /// See if we can combine two integer combines. This works only if we have
        /// identical statements!
        /// </summary>
        /// <param name="statement"></param>
        /// <returns></returns>
        public bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
            {
                throw new ArgumentNullException("statement");
            }

            var asint = statement as StatementIncrementInteger;

            if (asint == null)
            {
                return(false);
            }

            if (asint.Integer.RawValue != Integer.RawValue)
            {
                return(false);
            }

            //
            // We really don't have to do anything to combine. The
            // two statements are exactly identical. So, we can just
            // say "yes" and assume our caller will drop the combining.
            //

            return(true);
        }
コード例 #11
0
        /// <summary>
        /// We filter on one simple thing. If it is the case that the tests are the same,
        /// (identical), we do the combination, stealing the statements from the second one
        /// for ourselves. No renaming is required as this is a simple test!
        /// </summary>
        /// <param name="statement"></param>
        /// <returns></returns>
        public override bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
            {
                throw new ArgumentException("statement");
            }
            var other = statement as StatementFilter;

            if (other == null)
            {
                return(false);
            }

            if (other.TestExpression.RawValue != TestExpression.RawValue)
            {
                return(false);
            }

            // The combine is going to go (on some level). Exactly how it goes depends on the context
            // that the statement and this guy sit in. Specifically - if they are buried in different
            // if statements then we can't move non-identical things.
            // Here are the rules:
            // -> If both if's have the same parents, then we can combine them without worry.
            //    This is a little funny because we will often be combining them from different
            //    tree's (though the same). So we have to be a little careful looking backwards.
            //    This combination means that we can do this even if the statements in the body of the if
            //    are different.
            // -> If one is hidden behind another if statement, then we can combine iff:
            //      1) The one we are combining into is not the one hidden
            //      2) The bodies of the if statement are identical
            // -> If there is some other case, then we can't combine at all.
            //
            // Further notes:
            // -> This is not a general optimization. For example, if .Fill is called, that has side effects.
            //    But our code is such that we don't have to worry about that - .Fill is only going to get
            //    called once, and so those statements will never be identical.

            // Understand if the context of the two is the same or not (or how different).
            var itsContext = statement.WalkParents(includeThisStatment: true).Where(s => s is StatementFilter).Cast <StatementFilter>().ToLookup(s => s.TestExpression.RawValue);
            var myContext  = this.WalkParents(includeThisStatment: true).Where(s => s is StatementFilter).Cast <StatementFilter>().ToLookup(s => s.TestExpression.RawValue);

            if (itsContext.Count < myContext.Count)
            {
                // It is at a higher level than us, so we can't replicate it.
                return(false);
            }

            bool sameContext = false;

            if (itsContext.Count == myContext.Count)
            {
                sameContext = itsContext.Select(c => myContext.Contains(c.Key)).All(p => p);
            }

            // Since the if statements are the same, we can combine the interiors!
            return(Combine(other, opt, appendIfCantCombine: sameContext));
        }
コード例 #12
0
            public bool TryCombineStatement(IStatement statement, ICodeOptimizationService optimize)
            {
                var other = statement as CombineSameStatement;

                if (other == null)
                {
                    return(false);
                }
                return(other == this);
            }
コード例 #13
0
            public bool TryCombineStatement(IStatement statement, ICodeOptimizationService optimize)
            {
                var other = statement as CombineTestStatement;

                if (other == null)
                {
                    return(false);
                }
                return(optimize.TryRenameVarialbeOneLevelUp(other.vdecl2.ParameterName, vdecl2));
            }
コード例 #14
0
        public bool TryCombineStatement(IStatement statement, ICodeOptimizationService optimize)
        {
            var otherRtn = statement as StatementReturn;

            if (otherRtn == null)
            {
                return(false);
            }
            return(otherRtn._rtnValue.RawValue == _rtnValue.RawValue);
        }
コード例 #15
0
        /// <summary>
        /// We can combine only if the test strings are the same.
        /// </summary>
        /// <param name="statement"></param>
        /// <param name="optimize"></param>
        /// <returns></returns>
        public bool TryCombineStatement(IStatement statement, ICodeOptimizationService optimize)
        {
            if (!(statement is StatementThrowIfTrue))
            {
                return false;
            }
            var s = statement as StatementThrowIfTrue;
            var can = s._testValue == _testValue;

            return can;
        }
コード例 #16
0
        /// <summary>
        /// We can combine only if the test strings are the same.
        /// </summary>
        /// <param name="statement"></param>
        /// <param name="optimize"></param>
        /// <returns></returns>
        public bool TryCombineStatement(IStatement statement, ICodeOptimizationService optimize)
        {
            if (!(statement is StatementThrowIfTrue))
            {
                return(false);
            }
            var s   = statement as StatementThrowIfTrue;
            var can = s._testValue == _testValue;

            return(can);
        }
コード例 #17
0
        /// <summary>
        /// Absorb all the info from this combined block into this one.
        /// </summary>
        /// <param name="block"></param>
        protected bool Combine(StatementInlineBlockBase block, ICodeOptimizationService opt, bool appendIfCantCombine = true, bool moveIfIdentical = false)
        {
            var combineSucceeded = Combine(block.Statements, block, appendIfCantCombine: appendIfCantCombine, moveIfIdentical: moveIfIdentical);

            // Next, the variables that are defined inside this block (not defined by the block itself!).
            if (combineSucceeded)
            {
                Combine(block._variables);
            }

            // ANd we are done!
            return(combineSucceeded);
        }
コード例 #18
0
        /// <summary>
        /// Attempt to combine this statement. This is a little tricky. As it could be
        /// that the value we are accumulating is all that is different. In that case,
        /// we might be able to do the combination.
        /// </summary>
        /// <param name="statement"></param>
        /// <param name="opt"></param>
        /// <returns></returns>
        public bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
            {
                throw new ArgumentNullException("statement");
            }

            var otherAssign = statement as StatementAggregate;

            if (otherAssign == null)
            {
                return(false);
            }

            if (opt == null)
            {
                throw new ArgumentNullException("opt");
            }

            //
            // Simple case: everything is the same
            //

            if (ResultVariable.ParameterName == otherAssign.ResultVariable.ParameterName &&
                Expression.RawValue == otherAssign.Expression.RawValue)
            {
                return(true);
            }

            //
            // Next, see if we rename the accumulator everything would be identical
            //

            string tempRaw = Expression.RawValue.ReplaceVariableNames(ResultVariable.ParameterName, otherAssign.ResultVariable.ParameterName);

            if (tempRaw == otherAssign.Expression.RawValue)
            {
                // In order for this to work, we have to attempt to rename the variable that the other
                // guy owns. Since this variable is declared outside here, we have to call up in order
                // to have it run. Note that in this call it will call down into here to do the rename!

                return(opt.TryRenameVarialbeOneLevelUp(otherAssign.ResultVariable.ParameterName, ResultVariable));
            }

            //
            // There is nothing else we can do to figure out if this is the same, I"m afraid!
            //

            return(false);
        }
コード例 #19
0
        /// <summary>
        /// See if we can combine. For us that works only if we have
        /// identical statements!
        /// </summary>
        /// <param name="statement"></param>
        /// <returns></returns>
        public bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
            {
                throw new ArgumentNullException("statement");
            }
            var other = statement as StatementSimpleStatement;

            if (other == null)
            {
                return(false);
            }

            return(other.Line == Line &&
                   other.AddSemicolon == AddSemicolon);
        }
コード例 #20
0
        /// <summary>
        /// We can combine if our predicates look the same.
        /// </summary>
        /// <param name="statement"></param>
        /// <param name="optimize"></param>
        /// <returns></returns>
        public bool TryCombineStatement(IStatement statement, ICodeOptimizationService optimize)
        {
            if (statement == null)
            {
                throw new ArgumentNullException("statement");
            }

            var other = statement as StatementAnyAllDetector;

            if (other == null)
            {
                return(false);
            }

            if (Predicate == null)
            {
                if (other.Predicate != null)
                {
                    return(false);
                }
            }
            else
            {
                if (other.Predicate == null)
                {
                    return(false);
                }

                if (other.Predicate.RawValue != Predicate.RawValue ||
                    other.ResultValueToBe != ResultValueToBe)
                {
                    return(false);
                }
            }

            //
            // As long as nothing crazy is going on with result, then we
            // can definitely combine these two!
            //

            if (optimize == null)
            {
                throw new ArgumentNullException("optimize");
            }

            return(optimize.TryRenameVarialbeOneLevelUp(other.Result.RawValue, Result));
        }
コード例 #21
0
        /// <summary>
        /// Combine these statements.
        /// </summary>
        /// <param name="statement"></param>
        /// <param name="optimize"></param>
        /// <returns></returns>
        public bool TryCombineStatement(IStatement statement, ICodeOptimizationService optimize)
        {
            if (statement == null)
            {
                throw new ArgumentNullException("statement");
            }

            var other = statement as StatementRecordValue;

            if (other == null)
            {
                return(false);
            }

            if (other._recordOnlyFirstValue != _recordOnlyFirstValue)
            {
                return(false);
            }

            if (other._savers.Count != _savers.Count)
            {
                return(false);
            }

            foreach (var o in other._savers)
            {
                var ms = _savers.Any(s => s.Item2.RawValue == o.Item2.RawValue);
                if (!ms)
                {
                    return(false);
                }
            }

            if (optimize == null)
            {
                throw new ArgumentNullException("optimize");
            }

            foreach (var o in other._savers)
            {
                var ms = _savers.Where(s => s.Item2.RawValue == o.Item2.RawValue).First();
                optimize.TryRenameVarialbeOneLevelUp(o.Item1.RawValue, ms.Item1);
            }
            optimize.TryRenameVarialbeOneLevelUp(other._valueWasSeen.RawValue, _valueWasSeen);

            return(true);
        }
コード例 #22
0
        /// <summary>
        /// Combination means everything is identical except for the result variable. So the test is actually a little
        /// tricky.
        /// </summary>
        /// <param name="statement"></param>
        /// <param name="optimize"></param>
        /// <returns></returns>
        public bool TryCombineStatement(IStatement statement, ICodeOptimizationService optimize)
        {
            if (statement == null)
            {
                throw new ArgumentNullException("statement");
            }

            var other = statement as CPPCodeStatement;

            if (other == null)
            {
                return(false);
            }

            if (other._methodInfo != _methodInfo)
            {
                return(false);
            }

            // Make sure the lines of code are identical.
            var loc = _linesOfCode.Zip(other._linesOfCode, (u, t) => Tuple.Create(u, t));

            if (loc.Where(l => l.Item1 != l.Item2).Any())
            {
                return(false);
            }

            // Next, look at the parameters and make sure they are also the same.
            var plist = _paramReplacesments.Zip(other._paramReplacesments, (u, t) => Tuple.Create(u, t)).Where(p => p.Item1.Item2 != _cppResult.RawValue);

            if (plist.Where(p => p.Item1.Item1 != p.Item2.Item1).Any())
            {
                return(false);
            }
            if (plist.Where(p => p.Item1.Item2 != p.Item2.Item2).Any())
            {
                return(false);
            }

            // OK, they are the same. The one thing that has to be changed is how the result variable
            // in the other guy is used below. So we need to make that the "same".
            if (_cppResult.RawValue != other._cppResult.RawValue)
            {
                optimize.ForceRenameVariable(other._cppResult.RawValue, _cppResult.RawValue);
            }
            return(true);
        }
コード例 #23
0
        /// <summary>
        /// If we are the same, then combine!
        /// </summary>
        /// <param name="statement"></param>
        /// <param name="opt"></param>
        /// <returns></returns>
        public override bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
                throw new ArgumentNullException("statement");

            var other = statement as StatementLoopOverGroups;
            if (other == null)
                return false;

            if (_mapOfGroups.RawValue != other._mapOfGroups.RawValue)
                return false;

            // We declare group index by hand, so we have to do the renaming by hand here too.
            other.RenameVariable(other._groupIndex.RawValue, _groupIndex.RawValue);

            Combine(other, opt);
            return true;
        }
コード例 #24
0
        /// <summary>
        /// We can only combine if everything is the same!
        /// </summary>
        /// <param name="statement"></param>
        /// <param name="opt"></param>
        /// <returns></returns>
        public bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
                throw new ArgumentNullException("statement");

            var other = statement as StatementTestLoopPairwise;
            if (other == null)
                return false;

            if (_whatIsGood.ParameterName != other._whatIsGood.ParameterName
                || _test.RawValue != _test.RawValue)
                return false;

            //
            // Combining - nothing to do here.
            //

            return true;
        }
コード例 #25
0
        /// <summary>
        /// Try to combine this statement with another statement. The key thing abou tinline blocks
        /// is they are meaningless seperations of code. So we just keep lifing the empty ones
        /// up to the proper leve.
        /// </summary>
        /// <param name="statement"></param>
        /// <returns></returns>
        public override bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
                throw new ArgumentNullException("statement should not be null");

            if (!(statement is StatementInlineBlock))
            {
                return false;
            }

            //
            // Since it is an inline block, we can just try to combine the individual guys
            // that are deep in it. We do this by lifing statements out as much as we can.
            //

            Combine(statement as StatementInlineBlockBase, opt);

            return true;
        }
コード例 #26
0
        /// <summary>
        /// See if we can combine two integer combines. This works only if we have
        /// identical statements!
        /// </summary>
        /// <param name="statement"></param>
        /// <returns></returns>
        public bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
                throw new ArgumentNullException("statement");

            var asint = statement as StatementIncrementInteger;
            if (asint == null)
                return false;

            if (asint.Integer.RawValue != Integer.RawValue)
                return false;

            //
            // We really don't have to do anything to combine. The
            // two statements are exactly identical. So, we can just
            // say "yes" and assume our caller will drop the combining.
            //

            return true;
        }
コード例 #27
0
        /// <summary>
        /// Attempt to combine two of these statements. We can do this iff the source expression that
        /// we are testing is the same. Then the two indicies need to be renamed (it is assumed that we have total
        /// control - as you can see from the generated code above).
        /// </summary>
        /// <param name="statement"></param>
        /// <param name="opt"></param>
        /// <returns></returns>
        public override bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
            {
                throw new ArgumentNullException("statement");
            }

            var other = statement as StatementCheckLoopPairwise;

            if (other == null)
            {
                return(false);
            }

            if (_indciesToInspect.ParameterName != other._indciesToInspect.ParameterName)
            {
                return(false);
            }

            //
            // Rename the various guys. Note that index1 and index2 are declared by us. So it is only our sub-blocks that have to deal with
            // that. So we do a "local" renaming.
            //

            var rename = opt.TryRenameVarialbeOneLevelUp(other._whatIsGood.RawValue, _whatIsGood);

            if (!rename)
            {
                return(false);
            }
            other.RenameVariable(other._index1.RawValue, _index1.RawValue);
            other.RenameVariable(other._index2.RawValue, _index2.RawValue);

            //
            // Combine the sub-blocks now
            //

            Combine(other as StatementInlineBlockBase, opt);

            return(true);
        }
コード例 #28
0
        /// <summary>
        /// We need to try to combine statements here.
        /// </summary>
        /// <param name="statement"></param>
        /// <returns></returns>
        public override bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
            {
                throw new ArgumentNullException("statement");
            }

            var other = statement as StatementForLoop;

            if (other == null)
            {
                return(false);
            }

            // This shouldn't happen... we own the loop variable!!
            if (other._loopVariable == _loopVariable)
            {
                throw new InvalidOperationException("Loop variables identical in attempt to combine StatementForLoop!");
            }

            // If we are looping over the same thing, then we can combine.

            if (other.ArrayLength.RawValue != ArrayLength.RawValue)
            {
                return(false);
            }
            if (other.InitialValue.RawValue != InitialValue.RawValue)
            {
                return(false);
            }

            // We need to rename the loop variable in the second guy
            other.RenameVariable(other._loopVariable.ParameterName, _loopVariable.ParameterName);


            // Combine everything

            Combine(other, opt);

            return(true);
        }
コード例 #29
0
        /// <summary>
        /// Try to combine this statement with another statement. The key thing abou tinline blocks
        /// is they are meaningless seperations of code. So we just keep lifing the empty ones
        /// up to the proper leve.
        /// </summary>
        /// <param name="statement"></param>
        /// <returns></returns>
        public override bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
            {
                throw new ArgumentNullException("statement should not be null");
            }

            if (!(statement is StatementInlineBlock))
            {
                return(false);
            }

            //
            // Since it is an inline block, we can just try to combine the individual guys
            // that are deep in it. We do this by lifing statements out as much as we can.
            //

            Combine(statement as StatementInlineBlockBase, opt);

            return(true);
        }
コード例 #30
0
        /// <summary>
        /// We don't have the code to do the combination yet, so we have to bail!
        /// </summary>
        /// <param name="statement"></param>
        /// <returns></returns>
        public override bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
            {
                throw new ArgumentNullException("statement");
            }

            if (opt == null)
            {
                throw new ArgumentNullException("opt");
            }

            var other = statement as StatementIfOnCount;

            if (other == null)
            {
                return(false);
            }

            var issame = Comparison == other.Comparison &&
                         Limit.RawValue == other.Limit.RawValue;

            if (!issame)
            {
                return(false);
            }

            //
            // Now we have to rename the right, just in case...
            //

            if (!opt.TryRenameVarialbeOneLevelUp(other.Counter.RawValue, Counter))
            {
                return(false);
            }

            Combine(other, opt);

            return(true);
        }
コード例 #31
0
        /// <summary>
        /// Attempt to combine this statement. This is a little tricky. As it could be
        /// that the value we are accumulating is all that is different. In that case,
        /// we might be able to do the combination.
        /// </summary>
        /// <param name="statement"></param>
        /// <param name="opt"></param>
        /// <returns></returns>
        public bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
                throw new ArgumentNullException("statement");

            var otherAssign = statement as StatementAggregate;
            if (otherAssign == null)
                return false;

            if (opt == null)
                throw new ArgumentNullException("opt");

            //
            // Simple case: everything is the same
            //

            if (ResultVariable.ParameterName == otherAssign.ResultVariable.ParameterName
                && Expression.RawValue == otherAssign.Expression.RawValue)
                return true;

            //
            // Next, see if we rename the accumulator everything would be identical
            //

            string tempRaw = Expression.RawValue.ReplaceVariableNames(ResultVariable.ParameterName, otherAssign.ResultVariable.ParameterName);
            if (tempRaw == otherAssign.Expression.RawValue)
            {
                // In order for this to work, we have to attempt to rename the variable that the other
                // guy owns. Since this variable is declared outside here, we have to call up in order
                // to have it run. Note that in this call it will call down into here to do the rename!

                return opt.TryRenameVarialbeOneLevelUp(otherAssign.ResultVariable.ParameterName, ResultVariable);
            }

            //
            // There is nothing else we can do to figure out if this is the same, I"m afraid!
            //

            return false;
        }
コード例 #32
0
        /// <summary>
        /// Try to combine two of these statements. The key is what we are trying to minimize or maximize.
        /// </summary>
        /// <param name="statement"></param>
        /// <param name="opt"></param>
        /// <returns></returns>
        public bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
            {
                throw new ArgumentNullException("statement");
            }

            var other = statement as StatementMinMaxTest;

            if (other == null)
            {
                return(false);
            }

            if (CompareOperator != other.CompareOperator ||
                exprToMinOrMaximize.RawValue != other.exprToMinOrMaximize.RawValue)
            {
                return(false);
            }

            //
            // Everything else is dependent - so we can just rename it.
            //

            var cando = opt.TryRenameVarialbeOneLevelUp(other.MaxMinVariable.ParameterName, MaxMinVariable);

            if (!cando)
            {
                return(false);
            }
            cando = opt.TryRenameVarialbeOneLevelUp(other.vIsFilled.ParameterName, vIsFilled);
            if (!cando)
            {
                throw new InvalidOperationException("Unable to rename second variable in a chain for Min/Max operator!");
            }

            return(true);
        }
コード例 #33
0
        /// <summary>
        /// See if the two statements are compatible
        /// </summary>
        /// <param name="statement"></param>
        /// <param name="opt"></param>
        /// <returns></returns>
        public override bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
            {
                throw new ArgumentNullException("statement");
            }

            var other = statement as StatementLoopOverSortedPairValue;

            if (other == null)
            {
                return(false);
            }

            // Now inspect that the map records are the same

            var combinedInfo = _mapRecords.Zip(other._mapRecords, (f, s) => Tuple.Create(f, s));

            var candoIt = combinedInfo
                          .Select(i => i.Item1.mapRecords.RawValue == i.Item2.mapRecords.RawValue)
                          .All(b => b);

            if (!candoIt || _sortAscending != other._sortAscending)
            {
                return(false);
            }

            // Ok, we are going to do it. First, rename all the variables we can, and then
            // combine the code as best we can.

            foreach (var item in combinedInfo)
            {
                other.RenameVariable(item.Item2.indexVariable.ParameterName, item.Item1.indexVariable.RawValue);
            }
            Combine(other, opt);

            return(true);
        }
コード例 #34
0
        /// <summary>
        /// Try to combine two assign statements. Since this will be for totally
        /// trivial cases, this should be "easy" - only when they are the same.
        /// </summary>
        /// <param name="statement"></param>
        /// <returns></returns>
        public bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
            {
                throw new ArgumentNullException("statement");
            }

            if (opt == null)
            {
                throw new ArgumentNullException("opt");
            }

            var otherAssign = statement as StatementAssign;

            if (otherAssign == null)
            {
                return(false);
            }

            if (Expression.RawValue != otherAssign.Expression.RawValue)
            {
                return(false);
            }

            // If the statements are identical, then we can combine by default without having to do any
            // further work.

            if (otherAssign.ResultVariable.RawValue == ResultVariable.RawValue)
            {
                return(true);
            }

            // If we have declared, then we are sole owner - so we can force the change. Otherwise, we
            // need to let the infrastructure figure out where the declared is and change it from there.

            return(opt.TryRenameVarialbeOneLevelUp(otherAssign.ResultVariable.RawValue, ResultVariable));
        }
コード例 #35
0
 public override bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
 {
     throw new NotImplementedException();
 }
コード例 #36
0
 public IEnumerable<IStatement> TryCombineStatement(IStatement statement, ICodeOptimizationService optimize)
 {
     throw new NotImplementedException();
 }
コード例 #37
0
 /// <summary>
 /// See if we can't propagate this up, trying to combine it or bubble it up if there is something identical further up.
 /// </summary>
 /// <param name="statements"></param>
 /// <param name="item"></param>
 /// <param name="opter"></param>
 /// <returns></returns>
 private static bool BubleUpAndCombine(IStatementCompound statements, IStatement item, ICodeOptimizationService opter)
 {
     return MoveFirstWithCombine(statements, item, opter);
 }
コード例 #38
0
        /// <summary>
        /// Try to combine two of these statements. The key is what we are trying to minimize or maximize.
        /// </summary>
        /// <param name="statement"></param>
        /// <param name="opt"></param>
        /// <returns></returns>
        public bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
                throw new ArgumentNullException("statement");

            var other = statement as StatementMinMaxTest;
            if (other == null)
                return false;

            if (CompareOperator != other.CompareOperator
                || exprToMinOrMaximize.RawValue != other.exprToMinOrMaximize.RawValue)
                return false;

            //
            // Everything else is dependent - so we can just rename it.
            //

            var cando = opt.TryRenameVarialbeOneLevelUp(other.MaxMinVariable.ParameterName, MaxMinVariable);
            if (!cando)
                return false;
            cando = opt.TryRenameVarialbeOneLevelUp(other.vIsFilled.ParameterName, vIsFilled);
            if (!cando)
                throw new InvalidOperationException("Unable to rename second variable in a chain for Min/Max operator!");

            return true;
        }
コード例 #39
0
        /// <summary>
        /// Attempt to combine two of these statements. We can do this iff the source expression that
        /// we are testing is the same. Then the two indicies need to be renamed (it is assumed that we have total
        /// control - as you can see from the generated code above).
        /// </summary>
        /// <param name="statement"></param>
        /// <param name="opt"></param>
        /// <returns></returns>
        public override bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
                throw new ArgumentNullException("statement");

            var other = statement as StatementCheckLoopPairwise;
            if (other == null)
                return false;

            if (_indciesToInspect.ParameterName != other._indciesToInspect.ParameterName)
                return false;

            //
            // Rename the various guys. Note that index1 and index2 are declared by us. So it is only our sub-blocks that have to deal with
            // that. So we do a "local" renaming.
            //

            var rename = opt.TryRenameVarialbeOneLevelUp(other._whatIsGood.RawValue, _whatIsGood);
            if (!rename)
                return false;
            other.RenameVariable(other._index1.RawValue, _index1.RawValue);
            other.RenameVariable(other._index2.RawValue, _index2.RawValue);

            //
            // Combine the sub-blocks now
            //

            Combine(other as StatementInlineBlockBase, opt);

            return true;
        }
コード例 #40
0
        /// <summary>
                 /// See if we can combine statements
                 /// </summary>
                 /// <param name="statement"></param>
                 /// <param name="opt"></param>
                 /// <returns></returns>
        public override bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
                throw new ArgumentNullException("statement");

            var other = statement as StatementLoopOverGroupItems;
            if (other == null)
                return false;

            if (_groupArray.RawValue != other._groupArray.RawValue)
                return false;

            // We declare counter explicitly in the loop above - so we need to force the rename below rather
            // that rely on declared parameters.
            other.RenameVariable(other._counter.RawValue, _counter.RawValue);

            Combine(other, opt);
            return true;
        }
コード例 #41
0
 public bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
 {
     throw new NotImplementedException();
 }
コード例 #42
0
        /// <summary>
        /// We don't have the code to do the combination yet, so we have to bail!
        /// </summary>
        /// <param name="statement"></param>
        /// <returns></returns>
        public override bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
                throw new ArgumentNullException("statement");

            if (opt == null)
                throw new ArgumentNullException("opt");

            var other = statement as StatementIfOnCount;
            if (other == null)
                return false;

            var issame = Comparison == other.Comparison
                && Limit.RawValue == other.Limit.RawValue;

            if (!issame)
                return false;

            //
            // Now we have to rename the right, just in case...
            //

            if (!opt.TryRenameVarialbeOneLevelUp(other.Counter.RawValue, Counter))
                return false;

            Combine(other, opt);

            return true;
        }
コード例 #43
0
 public bool TestTryCombineStatement([PexAssumeUnderTest] StatementAnyAllDetector target, IStatement statement, ICodeOptimizationService optimize)
 {
     var result = target.TryCombineStatement(statement, optimize);
     return result;
 }
コード例 #44
0
        /// <summary>
        /// Move to the first one, seeing if we can combine as we go.
        /// We will attempt two things:
        /// 1. Is the statement above the "same"? If so, try to eliminate the down-level statement.
        /// 2. Can it be combined?
        /// </summary>
        /// <param name="statements"></param>
        /// <param name="item"></param>
        private static bool MoveFirstWithCombine(IStatementCompound statements, IStatement item, ICodeOptimizationService opter)
        {
            // First, move this forward as far as we can, and try to combine as we go.
            var previousStatements = statements.Statements.TakeWhile(s => s != item);

            // Now, see if we can move past each statement. If we can, see if they can be combined.
            foreach (var s in previousStatements.Reverse())
            {
                if (MakeStatmentsEquivalent(s, item))
                {
                    return true;
                }
                else if (StatementCommutes(s, item))
                {
                    if (s.TryCombineStatement(item, opter))
                    {
                        statements.Remove(item);
                        return true;
                    }
                }
            }

            return false;
        }
コード例 #45
0
 public bool TryCombineStatement(IStatement statement, ICodeOptimizationService optimize)
 {
     var other = statement as CombineTestStatement;
     if (other == null)
         return false;
     return optimize.TryRenameVarialbeOneLevelUp(other.vdecl2.ParameterName, vdecl2);
 }
コード例 #46
0
        /// <summary>
        /// Attempt to combine two record statements. We are a bit different, we have 
        /// an object we depend on - which is record... and that has to be the same. The
        /// other one we need to propagate.
        /// </summary>
        /// <param name="statement"></param>
        /// <returns></returns>
        public bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
                throw new ArgumentException("statement");

            if (opt == null)
                throw new ArgumentNullException("opt");

            var asRecord = statement as StatementRecordIndicies;
            if (asRecord == null)
                return false;

            if (_intToRecord.RawValue != asRecord._intToRecord.RawValue)
                return false;

            //
            // Since int to record is the same, we do a rename and move on!
            //

            return opt.TryRenameVarialbeOneLevelUp(asRecord._storageArray.RawValue, _storageArray);
        }
コード例 #47
0
 public bool TryCombineStatement(IStatement statement, ICodeOptimizationService optimize)
 {
     var other = statement as CombineSameStatement;
     if (other == null)
         return false;
     return other == this;
 }
コード例 #48
0
        /// <summary>
        /// Combine these statements.
        /// </summary>
        /// <param name="statement"></param>
        /// <param name="optimize"></param>
        /// <returns></returns>
        public bool TryCombineStatement(IStatement statement, ICodeOptimizationService optimize)
        {
            if (statement == null)
                throw new ArgumentNullException("statement");

            var other = statement as StatementRecordValue;
            if (other == null)
                return false;

            if (other._recordOnlyFirstValue != _recordOnlyFirstValue)
                return false;

            if (other._savers.Count != _savers.Count)
                return false;

            foreach (var o in other._savers)
            {
                var ms = _savers.Any(s => s.Item2.RawValue == o.Item2.RawValue);
                if (!ms)
                    return false;
            }

            if (optimize == null)
                throw new ArgumentNullException("optimize");

            foreach (var o in other._savers)
            {
                var ms = _savers.Where(s => s.Item2.RawValue == o.Item2.RawValue).First();
                optimize.TryRenameVarialbeOneLevelUp(o.Item1.RawValue, ms.Item1);
            }
            optimize.TryRenameVarialbeOneLevelUp(other._valueWasSeen.RawValue, _valueWasSeen);

            return true;
        }
コード例 #49
0
        /// <summary>
                 /// We can combine these two statements iff the array record we are looping
                 /// over is the same. Rename the index after that!
                 /// </summary>
                 /// <param name="statement"></param>
                 /// <returns></returns>
        public override bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
                throw new ArgumentNullException("statement");

            var otherPairLoop = statement as StatementPairLoop;
            if (otherPairLoop == null)
                return false;

            if (otherPairLoop.arrayRecord.RawValue != arrayRecord.RawValue)
                return false;

            // Just make sure the index guys are renamed!

            otherPairLoop.RenameVariable(otherPairLoop.index1.RawValue, index1.RawValue);
            otherPairLoop.RenameVariable(otherPairLoop.index2.RawValue, index2.RawValue);

            // Now, combine them!

            Combine(otherPairLoop, opt);

            return true;
        }
コード例 #50
0
        /// <summary>
        /// Combination means everything is identical except for the result variable. So the test is actually a little
        /// tricky.
        /// </summary>
        /// <param name="statement"></param>
        /// <param name="optimize"></param>
        /// <returns></returns>
        public bool TryCombineStatement(IStatement statement, ICodeOptimizationService optimize)
        {
            if (statement == null)
                throw new ArgumentNullException("statement");

            var other = statement as CPPCodeStatement;
            if (other == null)
                return false;

            if (other._methodInfo != _methodInfo)
                return false;

            // Make sure the lines of code are identical.
            var loc = _linesOfCode.Zip(other._linesOfCode, (u, t) => Tuple.Create(u, t));
            if (loc.Where(l => l.Item1 != l.Item2).Any())
            {
                return false;
            }

            // Next, look at the parameters and make sure they are also the same.
            var plist = _paramReplacesments.Zip(other._paramReplacesments, (u, t) => Tuple.Create(u, t)).Where(p => p.Item1.Item2 != _cppResult.RawValue);
            if (plist.Where(p => p.Item1.Item1 != p.Item2.Item1).Any())
            {
                return false;
            }
            if (plist.Where(p => p.Item1.Item2 != p.Item2.Item2).Any())
            {
                return false;
            }

            // OK, they are the same. The one thing that has to be changed is how the result variable
            // in the other guy is used below. So we need to make that the "same".
            if (_cppResult.RawValue != other._cppResult.RawValue)
            {
                optimize.ForceRenameVariable(other._cppResult.RawValue, _cppResult.RawValue);
            }
            return true;
        }
コード例 #51
0
        public bool TestTryCombineStatement([PexAssumeUnderTest] StatementCheckLoopPairwise target, IStatement statement, ICodeOptimizationService opt)
        {
            var actual = target.TryCombineStatement(statement, opt);

            return(actual);
        }
コード例 #52
0
 public bool TestTryCombine([PexAssumeUnderTest] StatementPairLoop pairloop, IStatement statement, ICodeOptimizationService codeOpt)
 {
     var result = pairloop.TryCombineStatement(statement, codeOpt);
     return result;
 }
コード例 #53
0
 /// <summary>
 /// Since this statement has an external side-effect, it can't be combined
 /// ever - it should never appear mroe than once.
 /// </summary>
 /// <param name="statement"></param>
 /// <param name="optimize"></param>
 /// <returns></returns>
 public bool TryCombineStatement(IStatement statement, ICodeOptimizationService optimize)
 {
     return false;
 }
コード例 #54
0
        /// <summary>
        /// See if we can combine. For us that works only if we have
        /// identical statements!
        /// </summary>
        /// <param name="statement"></param>
        /// <returns></returns>
        public bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
                throw new ArgumentNullException("statement");
            var other = statement as StatementSimpleStatement;
            if (other == null)
                return false;

            return other.Line == Line
                && other.AddSemicolon == AddSemicolon;
        }
コード例 #55
0
        /// <summary>
        /// See if the two statements are compatible
        /// </summary>
        /// <param name="statement"></param>
        /// <param name="opt"></param>
        /// <returns></returns>
        public override bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
                throw new ArgumentNullException("statement");

            var other = statement as StatementLoopOverSortedPairValue;
            if (other == null)
                return false;

            // Now inspect that the map records are the same

            var combinedInfo = _mapRecords.Zip(other._mapRecords, (f, s) => Tuple.Create(f, s));

            var candoIt = combinedInfo
                .Select(i => i.Item1.mapRecords.RawValue == i.Item2.mapRecords.RawValue)
                .All(b => b);

            if (!candoIt || _sortAscending != other._sortAscending)
                return false;

            // Ok, we are going to do it. First, rename all the variables we can, and then
            // combine the code as best we can.

            foreach (var item in combinedInfo)
            {
                other.RenameVariable(item.Item2.indexVariable.ParameterName, item.Item1.indexVariable.RawValue);
            }
            Combine(other, opt);

            return true;
        }
コード例 #56
0
        /// <summary>
        /// We can combine if our predicates look the same.
        /// </summary>
        /// <param name="statement"></param>
        /// <param name="optimize"></param>
        /// <returns></returns>
        public bool TryCombineStatement(IStatement statement, ICodeOptimizationService optimize)
        {
            if (statement == null)
                throw new ArgumentNullException("statement");

            var other = statement as StatementAnyAllDetector;
            if (other == null)
                return false;

            if (Predicate == null)
            {
                if (other.Predicate != null)
                    return false;
            }
            else
            {
                if (other.Predicate == null)
                    return false;

                if (other.Predicate.RawValue != Predicate.RawValue
                    || other.ResultValueToBe != ResultValueToBe)
                    return false;
            }

            //
            // As long as nothing crazy is going on with result, then we
            // can definitely combine these two!
            //

            if (optimize == null)
                throw new ArgumentNullException("optimize");

            return optimize.TryRenameVarialbeOneLevelUp(other.Result.RawValue, Result);
        }
コード例 #57
0
 /// <summary>
 /// Since this statement has an external side-effect, it can't be combined
 /// ever - it should never appear mroe than once.
 /// </summary>
 /// <param name="statement"></param>
 /// <param name="optimize"></param>
 /// <returns></returns>
 public bool TryCombineStatement(IStatement statement, ICodeOptimizationService optimize)
 {
     return(false);
 }
コード例 #58
0
        /// <summary>
                 /// Try to combine two of these guys
                 /// </summary>
                 /// <param name="statement"></param>
                 /// <returns></returns>
        public override bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt)
        {
            if (statement == null)
                throw new ArgumentNullException();
            if (this == statement)
                throw new ArgumentException("Can't comebine with self!");

            var otherLoop = statement as StatementLoopOverGood;
            if (otherLoop == null)
                return false;

            // Are they the same? _index is independent and we can alter it.
            if (otherLoop._indexIsGood.RawValue == _indexIsGood.RawValue
                && otherLoop._indiciesToCheck.RawValue == _indiciesToCheck.RawValue)
            {
                if (!(opt.TryRenameVarialbeOneLevelUp(otherLoop._index.RawValue, _index)))
                    return false;

                Combine(otherLoop, opt);
                return true;
            }
            else
            {
                return false;
            }
        }
コード例 #59
0
        public bool TestTryCombineStatement([PexAssumeUnderTest] StatementCheckLoopPairwise target, IStatement statement, ICodeOptimizationService opt)
        {
            var actual = target.TryCombineStatement(statement, opt);

            return actual;
        }
コード例 #60
0
 /// <summary>
 /// See if we can't propagate this up, trying to combine it or bubble it up if there is something identical further up.
 /// </summary>
 /// <param name="statements"></param>
 /// <param name="item"></param>
 /// <param name="opter"></param>
 /// <returns></returns>
 private static bool BubleUpAndCombine(IStatementCompound statements, IStatement item, ICodeOptimizationService opter)
 {
     return(MoveFirstWithCombine(statements, item, opter));
 }