/// <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); } }
/// <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); }
public bool TryCombineStatement(IStatement statement, ICodeOptimizationService optimize) { var otherRtn = statement as StatementReturn; if (otherRtn == null) return false; return otherRtn._rtnValue.RawValue == _rtnValue.RawValue; }
/// <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); }
/// <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)); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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)); }
public bool TryCombineStatement(IStatement statement, ICodeOptimizationService optimize) { var other = statement as CombineSameStatement; if (other == null) { return(false); } return(other == this); }
public bool TryCombineStatement(IStatement statement, ICodeOptimizationService optimize) { var other = statement as CombineTestStatement; if (other == null) { return(false); } return(optimize.TryRenameVarialbeOneLevelUp(other.vdecl2.ParameterName, vdecl2)); }
public bool TryCombineStatement(IStatement statement, ICodeOptimizationService optimize) { var otherRtn = statement as StatementReturn; if (otherRtn == null) { return(false); } return(otherRtn._rtnValue.RawValue == _rtnValue.RawValue); }
/// <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; }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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)); }
/// <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); }
/// <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); }
/// <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; }
/// <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; }
/// <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; }
/// <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; }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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; }
/// <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); }
/// <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); }
/// <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)); }
public override bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt) { throw new NotImplementedException(); }
public IEnumerable<IStatement> TryCombineStatement(IStatement statement, ICodeOptimizationService optimize) { throw new NotImplementedException(); }
/// <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); }
/// <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; }
/// <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; }
/// <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; }
public bool TryCombineStatement(IStatement statement, ICodeOptimizationService opt) { throw new NotImplementedException(); }
/// <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; }
public bool TestTryCombineStatement([PexAssumeUnderTest] StatementAnyAllDetector target, IStatement statement, ICodeOptimizationService optimize) { var result = target.TryCombineStatement(statement, optimize); return result; }
/// <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; }
public bool TryCombineStatement(IStatement statement, ICodeOptimizationService optimize) { var other = statement as CombineTestStatement; if (other == null) return false; return optimize.TryRenameVarialbeOneLevelUp(other.vdecl2.ParameterName, vdecl2); }
/// <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); }
public bool TryCombineStatement(IStatement statement, ICodeOptimizationService optimize) { var other = statement as CombineSameStatement; if (other == null) return false; return other == this; }
/// <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; }
/// <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; }
/// <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; }
public bool TestTryCombineStatement([PexAssumeUnderTest] StatementCheckLoopPairwise target, IStatement statement, ICodeOptimizationService opt) { var actual = target.TryCombineStatement(statement, opt); return(actual); }
public bool TestTryCombine([PexAssumeUnderTest] StatementPairLoop pairloop, IStatement statement, ICodeOptimizationService codeOpt) { var result = pairloop.TryCombineStatement(statement, codeOpt); return result; }
/// <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; }
/// <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; }
/// <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; }
/// <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); }
/// <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); }
/// <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; } }
public bool TestTryCombineStatement([PexAssumeUnderTest] StatementCheckLoopPairwise target, IStatement statement, ICodeOptimizationService opt) { var actual = target.TryCombineStatement(statement, opt); return actual; }
/// <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)); }