コード例 #1
0
        private bool LoopExpansion(ref DILOperationSet operations)
        {
            if (!operations.ContainsLoops())
            {
                return(false);
            }

            for (int i = 0; i < operations.Count; i++)
            {
                var operation = operations[i];
                if (!(operation is LoopOp))
                {
                    continue;
                }

                var loopOp   = (LoopOp)operation;
                var unrolled = loopOp.Unroll();
                if (unrolled.WasLoopUnrolled)
                //if (false)
                {
                    operations.RemoveAt(i); // remove the loop
                    operations.InsertRange(i, unrolled.UnrolledInstructions);
                    return(true);           // One loop at a time
                }

                // TODO: The problem I'm having with loop unrolling is with the two statements
                operations.RemoveAt(i);
                operations.Insert(i, new LoopOp(unrolled.UnrolledInstructions));
            }

            return(false);
        }
コード例 #2
0
        private bool CompactRepeatableOperations(ref DILOperationSet operations)
        {
            var wasOptimized = false;

            for (int i = 0; i < operations.Count; i++)
            {
                var loopInstruction = operations[i] as LoopOp;
                if (loopInstruction != null)
                {
                    var loopInstructions = loopInstruction.Instructions;
                    CompactRepeatableOperations(ref loopInstructions);
                    loopInstruction.Instructions = loopInstructions;
                    continue;
                }

                var repeatable = operations[i] as IRepeatable;
                if (repeatable != null)
                {
                    if (repeatable.Repeat(operations, i))
                    {
                        wasOptimized = true;
                    }
                }
            }

            return(wasOptimized);
        }
コード例 #3
0
        public bool Optimize(ref DILOperationSet optimized)
        {
            while (CompactRepeatableOperations(ref optimized))
            {
            }

            // expand all the simple loops
            while (LoopExpansion(ref optimized))
            {
                return(true); // After some loops have been expanded, there might be new repeatable operations which need to be compacted.
            }

            optimized.RemoveAll(i => i == null);

            //if (!WereConstantsSubstituted)
            //{
            //    int currentIndex = 0, nextIOOperationIndex, currentPtrIndex = 0;
            //    while (
            //        currentIndex <= optimized.Count &&
            //        (nextIOOperationIndex = optimized.FindIndex(currentIndex,
            //            i => i is WriteOp || i is ReadOp || i is LoopOp)) != -1)
            //    {
            //        var subOperationSet = new DILOperationSet(optimized.Skip(currentIndex).Take(nextIOOperationIndex - currentIndex));

            //        var walk = new CodeWalker().Walk(subOperationSet, subOperationSet.Count);
            //        //var walk = new CodeWalker().Walk(optimized, nextIOOperationIndex);
            //        //var walk = Walk(i);

            //        var tempSet = new DILOperationSet();
            //        foreach (var cell in walk.Domain)
            //        {
            //            if (cell.Value != 0)
            //            {
            //                tempSet.Add(new AdditionMemoryOp(cell.Key, cell.Value));
            //            }
            //        }

            //        if (walk.EndPtrPosition != 0)
            //        {
            //            tempSet.Add(new PtrOp(walk.EndPtrPosition));
            //        }

            //        //foreach (var miscOperation in walk.MiscOperations)
            //        //{
            //        //    tempSet.Add(miscOperation.Value);
            //        //}

            //        currentPtrIndex += walk.EndPtrPosition;

            //        //if (nextIOOperationIndex - currentIndex < optimized.Count)
            //        //{
            //        //    var op = optimized[nextIOOperationIndex - currentIndex];
            //        //    if (op is ReadOp || op is WriteOp)
            //        //    {
            //        //        ((IOffsettable)op).Offset = currentPtrIndex;
            //        //    }

            //        //}

            //        optimized.RemoveRange(currentIndex, nextIOOperationIndex - currentIndex);
            //        optimized.InsertRange(currentIndex, tempSet);

            //        currentIndex += tempSet.Count + 1; // + 1 to skip the IO operation

            //        //// If the instruction that we stopped at is a loop, then break from
            //        //// this optimization step because then we wouldn't be able to do
            //        //// any more walks.
            //        //// This may change in the future...
            //        //if (optimized[currentIndex - 1] is LoopOp)
            //        //{
            //        //    break;
            //        //}
            //    }
            //}

            /* Constant Substitution */
            //if (CanWeSubstituteConstants())
            //{
            //    if (SubstituteConstants(ref optimized))
            //    {
            //        return true;
            //    }
            //}

            /* String walking */
            //var stringWalkResults = StringWalk();
            //if (stringWalkResults != null && stringWalkResults.Strings.Count > 0)
            //{
            //    optimized.Clear();
            //    var combine = String.Join("", stringWalkResults.Strings);
            //    optimized.Add(new WriteLiteralOp(combine));

            //    return true;
            //}

            return(false);
        }
コード例 #4
0
        /// <summary>
        /// Optimization #6:
        /// Constant substitution
        ///
        /// TODO: This method has some inconsistencies when setting the offset with the new memory operations.
        ///       For some memory operations, I'm using "new {Op}(ptr + {op}.Offset)"
        ///       and for others I'm just using "new {Op}({op}.Offset)".
        ///       I'm pretty sure this inconsistency is causing some problems.
        /// </summary>
        /// <param name="operations"></param>
        private bool SubstituteConstants(ref DILOperationSet operations)
        {
            if (WereConstantsSubstituted)
            {
                return(false);
            }

            var ptr = 0;
            var arr = operations.ToArray();
            var didAnysubstitutions = false;

            for (int i = 0; i < arr.Length; i++)
            {
                var operation = arr[i];
                if (operation is AdditionMemoryOp)
                {
                    var add = (AdditionMemoryOp)operation;
                    if (add.Constant == null)
                    {
                        arr[i] = new AdditionMemoryOp(ptr + add.Offset, add.Scalar, new ConstantValue(ptr + add.Offset));
                        didAnysubstitutions = true;
                    }
                }
                else if (operation is MultiplicationMemoryOp)
                {
                    var mul = (MultiplicationMemoryOp)operation;
                    if (mul.Constant == null)
                    {
                        arr[i] = new MultiplicationMemoryOp(ptr + mul.Offset, mul.Scalar, new ConstantValue(ptr + mul.Offset), new ConstantValue(ptr));
                    }
                }
                else if (operation is AssignOp)
                {
                    var ass = arr[i] as AssignOp;
                    if (ass.Constant == null)
                    {
                        arr[i] = new AssignOp(ptr + ass.Offset, ass.Value, new ConstantValue(ptr + ass.Offset));
                        didAnysubstitutions = true;
                    }
                }
                else if (operation is PtrOp)
                {
                    arr[i] = null; // if we're using constants, then we don't need pointer movements
                    var ptrOp = (PtrOp)operation;
                    ptr += ptrOp.Delta;
                    //didAnysubstitutions = true;
                }
                else if (operation is WriteOp)
                {
                    var write = ((WriteOp)arr[i]);
                    if (write.Constant == null)
                    {
                        arr[i] = new WriteOp(write.Offset, write.Repeated, new ConstantValue(ptr));
                        didAnysubstitutions = true;
                    }
                }
                else if (operation is ReadOp)
                {
                    var read = ((ReadOp)arr[i]);
                    if (read.Constant == null)
                    {
                        arr[i] = new ReadOp(read.Offset, read.Repeated, new ConstantValue(ptr));
                        didAnysubstitutions = true;
                    }
                }
            }

            var list = arr.ToList();

            list.RemoveAll(l => l == null);

            operations = new DILOperationSet(list);

            operations.WereConstantsSubstituted = true;

            return(didAnysubstitutions);
        }