Exemple #1
0
        protected override bool InnerOptimize(OptimizationContext context, Instruction matchedInstruction, Backtracer backtracer, int i)
        {
            var changed       = false;
            var j             = i;
            var patchedLabels = new Dictionary <(ushort label, short offset), ushort>();

            context.RemoveAt(j);

            while (!IsChainBreaker(context[j], matchedInstruction, new BacktracerView(backtracer, j - 1, false)))
            {
                var instruction = context[j];
                switch (instruction.Type)
                {
                case InstructionType.BoundsCheck:
                case InstructionType.Char:
                    var targetLabel = instruction.Label;
                    if (patchedLabels.TryGetValue((targetLabel, matchedInstruction.Offset), out var newTarget))
                    {
                        targetLabel = newTarget;
                    }
                    else
                    {
                        var oldLabel = targetLabel;
                        targetLabel = AddStub(context, targetLabel, matchedInstruction, ref j);
                        patchedLabels[(oldLabel, matchedInstruction.Offset)] = targetLabel;
        protected override bool InnerOptimize(OptimizationContext context, Instruction matchedInstruction, Backtracer backtracer, int i)
        {
            var changed       = false;
            var j             = i;
            var patchedLabels = new Dictionary <(ushort label, short offset), ushort>();
            var offset        = matchedInstruction.Offset;
            var removedAt     = 0;

            context.RemoveAt(j);

            while (!IsChainBreaker(context[j], Instruction.Advance(offset), null))
            {
                var instruction = context[j];
                switch (instruction.Type)
                {
                case InstructionType.Advance:
                    offset   += instruction.Offset;
                    removedAt = j;
                    context.RemoveAt(j);
                    break;

                case InstructionType.BoundsCheck:
                case InstructionType.Char:
                    var targetLabel = instruction.Label;
                    if (context[context.GetLabelPosition(targetLabel) + 1].Type != InstructionType.RestorePosition)
                    {
                        if (patchedLabels.TryGetValue((targetLabel, offset), out var newTarget))
                        {
                            targetLabel = newTarget;
                        }
                        else if (offset != 0)
                        {
                            var oldLabel = targetLabel;
                            targetLabel = AddStub(context, targetLabel, Instruction.Advance(offset), ref j);
                            patchedLabels[(oldLabel, offset)] = targetLabel;
        public string GetSqlText(SelectQuery query)
        {
            var provider  = ((IDataContext)this).CreateSqlProvider();
            var optimizer = ((IDataContext)this).GetSqlOptimizer();

            var optimizationContext = new OptimizationContext(new EvaluationContext(SqlParameterValues.Empty), null, false);
            var statement           = (SqlSelectStatement)optimizer.Finalize(new SqlSelectStatement(query));

            statement = (SqlSelectStatement)optimizer.PrepareStatementForRemoting(statement, MappingSchema, optimizationContext.Context);

            var cc = provider.CommandCount(statement);
            var sb = new StringBuilder();

            var commands = new string[cc];

            for (var i = 0; i < cc; i++)
            {
                sb.Length = 0;

                provider.BuildSql(i, statement, sb, optimizationContext);
                commands[i] = sb.ToString();
            }

            return(string.Join("\n\n", commands));
        }
Exemple #4
0
        protected override void BuildSql(int commandNumber, SqlStatement statement, StringBuilder sb, OptimizationContext optimizationContext, int indent, bool skipAlias)
        {
            Statement           = statement;
            StringBuilder       = sb;
            OptimizationContext = optimizationContext;
            Indent    = indent;
            SkipAlias = skipAlias;

            if (_identityField != null)
            {
                indent += 2;

                AppendIndent().AppendLine("SELECT");
                AppendIndent().Append('\t');
                BuildExpression(_identityField, false, true);
                sb.AppendLine();
                AppendIndent().AppendLine("FROM");
                AppendIndent().AppendLine("\tNEW TABLE");
                AppendIndent().Append('\t').AppendLine(OpenParens);
            }

            base.BuildSql(commandNumber, statement, sb, optimizationContext, indent, skipAlias);

            if (_identityField != null)
            {
                sb.AppendLine("\t)");
            }
        }
Exemple #5
0
        private static bool RemoveDeadCodeAfter(OptimizationContext context, int[] labelsUsed, int i, Instruction instruction, bool subtractValues = false)
        {
            var changed = false;

            while (i + 1 < context.Count && !context[i + 1].Matches(InstructionType.MarkLabel))
            {
                if (subtractValues)
                {
                    switch (context[i + 1].Type)
                    {
                    case InstructionType.Call:
                        foreach (var(_, targetLabel) in context.FailureLabelMap[instruction.Data2].Mapping)
                        {
                            labelsUsed[targetLabel]--;
                        }
                        break;

                    case InstructionType.Char:
                    case InstructionType.BoundsCheck:
                    case InstructionType.Jump:
                        labelsUsed[instruction.Label]--;
                        break;
                    }
                }

                context.RemoveAt(i + 1, true);
                changed = true;
            }

            return(changed);
        }
Exemple #6
0
        private bool HasVariableAround(OptimizationContext context, int i, ushort variable)
        {
            var pos = i;

            while (pos > 0 && context[pos].Type == InstructionType.StorePosition)
            {
                if (context[pos].Data1 == variable)
                {
                    return(true);
                }

                pos--;
            }

            pos = i;
            while (pos < context.Count && context[pos].Type == InstructionType.StorePosition)
            {
                if (context[pos].Data1 == variable)
                {
                    return(true);
                }

                pos++;
            }

            return(false);
        }
Exemple #7
0
        protected ushort?FindOrMarkExistingStub(OptimizationContext context, Instruction[] neededInstructions, ushort targetLabel, ref int position)
        {
            for (var i = 0; i < context.Count; i++)
            {
                if (SequencesEqual(context, i, neededInstructions) &&
                    (context[i + neededInstructions.Length].Matches(InstructionType.MarkLabel, targetLabel) || context[i + neededInstructions.Length].Matches(InstructionType.Jump, targetLabel)))
                {
                    if (i > 0 && context[i - 1].Matches(InstructionType.MarkLabel, out var existingLabel))
                    {
                        return(existingLabel);
                    }
                    else
                    {
                        var newLabel = context.LabelAllocator++;
                        context.Insert(i, Instruction.MarkLabel(newLabel));
                        if (position >= i)
                        {
                            position++;
                        }

                        return(newLabel);
                    }
                }
            }

            return(null);
        }
Exemple #8
0
        /// <summary>
        /// Optimizes the provided expression using an <see cref="OptimizationContext{TSettings}"/>
        /// created with <see cref="OptimizationContext.CreateDefault(DefaultOptimizationSettings?, IEnumerable{IOptimizationPass{DefaultOptimizationSettings}})"/>
        /// </summary>
        /// <param name="expr">the expression to optimize</param>
        /// <returns>the optimized expression</returns>
        public override MathExpression Optimize(MathExpression expr)
        {
            var ctx = OptimizationContext.CreateDefault(OptimizerSettings, OptimizerPasses);

            ctx.SetParentDataContext(SharedDataStore);
            return(ctx.Optimize(expr));
        }
Exemple #9
0
        public override bool Optimize(OptimizationContext context)
        {
            var changed    = false;
            var offsetInfo = new VariableOffset[context.Count];

            for (var i = 0; i < offsetInfo.Length; i++)
            {
                offsetInfo[i] = new VariableOffset();
            }

            BuildOffsetInfo(context, offsetInfo);

            for (var i = context.Count - 1; i >= 0; i--)
            {
                var instruction = context[i];
                switch (instruction.Type)
                {
                case InstructionType.RestorePosition:
                    var offset = offsetInfo[i].Get(instruction.Data1);
                    if (offset == 0)
                    {
                        changed = true;
                        context.RemoveAt(i);
                    }
                    else if (offset > 0)
                    {
                        changed    = true;
                        context[i] = Instruction.Advance((short)-offset);
                    }
                    break;
                }
            }

            return(changed);
        }
Exemple #10
0
        protected override bool InnerOptimize(OptimizationContext context, Instruction matchedInstruction, Backtracer backtracer, int i)
        {
            var changed = false;
            var j       = i;

            context.RemoveAt(j);

            while (!IsChainBreaker(context[j], matchedInstruction, null))
            {
                var instruction = context[j];
                if (instruction.Matches(InstructionType.BoundsCheck, matchedInstruction.Label))
                {
                    changed            = true;
                    matchedInstruction = Instruction.BoundsCheck(instruction.Label, Math.Max(instruction.Offset, context[j].Offset));
                    context.RemoveAt(j);
                }
                else
                {
                    j++;
                }
            }

            context.Insert(i, matchedInstruction);

            return(changed);
        }
Exemple #11
0
        public CharCheckEntry MatchFail(OptimizationContext context, Instruction instruction)
        {
            var failing = FailingCharacters.Clone();

            AddEntry(instruction, true, instruction.Offset, failing);

            return(new CharCheckEntry(MatchingCharacters, failing));
        }
Exemple #12
0
        public NdState MatchFail(OptimizationContext context, Instruction instruction, int offset)
        {
            var failing = FailingCharacters.Clone();

            AddEntry(instruction, true, offset, failing);

            return(new NdState(Variable, Vug, PositionA, PositionB, AdvancesA, AdvancesB, MinBounds, MaxBounds, VarAs, VarBs, MatchingCharacters, failing));
        }
        public void BinaryCombinerLiteralCombinerPasses(MathExpression input, MathExpression expect)
        {
            var context = OptimizationContext.CreateWith(new DefaultOptimizationSettings(), new BinaryExpressionCombinerPass(), new LiteralCombinerPass());

            var actual = context.Optimize(input);

            Assert.Equal(expect, actual);
        }
        public void ExponentConstantReductionPass(MathExpression input, MathExpression expect)
        {
            var context = OptimizationContext.CreateWith(null, new BuiltinExponentConstantReductionPass());

            var actual = context.Optimize(input);

            Assert.Equal(expect, actual);
        }
        public void LiteralCombinerPass(MathExpression input, MathExpression expect)
        {
            var context = OptimizationContext.CreateWith(null, new LiteralCombinerPass());

            var actual = context.Optimize(input);

            Assert.Equal(expect, actual);
        }
Exemple #16
0
        public override bool Optimize(OptimizationContext context)
        {
            var changed = false;

            for (var i = context.Count - 1; i >= 0; i--)
            {
                var instructionCount = context.Count;
                var instruction      = context[i];
                switch (instruction.Type)
                {
                // TODO: Can we optimize a Call-instruction here?
                case InstructionType.Char:
                case InstructionType.BoundsCheck:
                case InstructionType.Jump:
                {
                    var backtracer = new BacktracerView(context.Backtracer, i, true);
                    if (!instruction.IsCharOrBoundsCheck)
                    {
                        backtracer = new BacktracerView(context.Backtracer, i - 1, false);
                    }

                    var result = InstructionHelper.FindJumpTargetEx(context, backtracer, context.GetLabelPosition(instruction.Label), FullPathSearch, false);
                    if (!context[result.Position - 1].Matches(InstructionType.MarkLabel, instruction.Label))
                    {
                        if (context[result.Position - 1].Matches(InstructionType.MarkLabel, out var newTarget))
                        {
                            context.NonDestructiveUpdate(i, instruction.WithLabel(newTarget));
                        }
                        else
                        {
                            var newLabel = context.LabelAllocator++;
                            context.NonDestructiveUpdate(i, instruction.WithLabel(newLabel));
                            context.Insert(result.Position, Instruction.MarkLabel(newLabel), true);
                        }

                        changed = true;
                    }
                }
                break;
                }
            }

            for (var i = context.Count - 1; i >= 0; i--)
            {
                var instructionCount = context.Count;
                var instruction      = context[i];
                if (instruction.Matches(InstructionType.Jump, out var targetLabel))
                {
                    var jumpingTo = context[context.GetLabelPosition(targetLabel) + 1];
                    if (jumpingTo.Matches(InstructionType.Return))
                    {
                        context[i] = jumpingTo;
                    }
                }
            }

            return(changed);
        }
Exemple #17
0
        private bool[] CreateUsageGraph(bool[] graph, ushort variable, OptimizationContext context, int pos)
        {
            var positionStack = new Stack <int>();

            positionStack.Push(pos);

            while (positionStack.Count > 0)
            {
                var currentPos  = positionStack.Pop();
                var instruction = context[currentPos];
                if (!graph[currentPos])
                {
                    graph[currentPos] = true;
                    switch (instruction.Type)
                    {
                    case InstructionType.StorePosition when instruction.Data1 == variable:
                        break;

                    case InstructionType.MarkLabel:
                        for (var i = 0; i < context.Count; i++)
                        {
                            switch (context[i].Type)
                            {
                            case InstructionType.BoundsCheck:
                            case InstructionType.Char:
                            case InstructionType.Jump:
                                if (context[i].Label == instruction.Label)
                                {
                                    positionStack.Push(i);
                                }
                                break;

                            case InstructionType.Call:
                                foreach (var(_, jumpTarget) in context.FailureLabelMap[context[i].Data2].Mapping)
                                {
                                    if (jumpTarget == instruction.Label)
                                    {
                                        positionStack.Push(i);
                                    }
                                }
                                break;
                            }
                        }
                        goto default;

                    default:
                        if (currentPos > 0 && context[currentPos - 1].Type != InstructionType.Jump && context[currentPos - 1].Type != InstructionType.Return)
                        {
                            positionStack.Push(currentPos - 1);
                        }
                        break;
                    }
                }
            }

            return(graph);
        }
        public override bool Optimize(OptimizationContext context)
        {
            var changed = false;

            changed |= Deduplicate(context);
            //changed |= Stitch(context);

            return(changed);
        }
Exemple #19
0
        public NdState MatchSuccess(OptimizationContext context, Instruction instruction, int offset)
        {
            var matching = MatchingCharacters.Clone();

            AddEntry(instruction, true, offset, matching);

            matching[offset].RemoveAll(existing => InstructionHelper.NonJumpMatchWillFail(context, existing, instruction));

            return(new NdState(Variable, Vug, PositionA, PositionB, AdvancesA, AdvancesB, MinBounds, MaxBounds, VarAs, VarBs, matching, FailingCharacters));
        }
Exemple #20
0
        public CharCheckEntry MatchSuccess(OptimizationContext context, Instruction instruction)
        {
            var matching = MatchingCharacters.Clone();

            AddEntry(instruction, true, instruction.Offset, matching);

            matching[instruction.Offset].RemoveAll(existing => InstructionHelper.NonJumpMatchWillFail(context, existing, instruction));

            return(new CharCheckEntry(matching, FailingCharacters));
        }
Exemple #21
0
        private bool Analyze(OptimizationContext context, NdState initialState)
        {
            var processed = new List <NdState> [context.Count];

            for (var i = 0; i < processed.Length; i++)
            {
                processed[i] = new List <NdState>();
            }

            var overflowProtection = 0;

            var stack = new Stack <NdState>();

            stack.Push(initialState);
            while (stack.Count > 0)
            {
                if (stack.Count > context.Count)
                {
                    // Bailout if stack starts to explode
                    return(false);
                }
                else if (overflowProtection++ >= context.Count * 250)
                {
                    // Or if we're just taking too long
                    return(false);
                }

                var current = stack.Pop();
                if (current.AAndBAreSameState() || !validPositionsForB[current.PositionB] || processed[current.PositionA].Any(item => current.PracticallyEquivalent(item, context, stack)))
                {
                    // Already processed this state.
                    continue;
                }

                processed[current.PositionA].Add(current);

                NdStateView view;
                if (current.AdvancesB < current.AdvancesA || context[current.PositionA].Matches(InstructionType.Return))
                {
                    view = current.B;
                }
                else
                {
                    view = current.A;
                }

                if (!Step(context, stack, view, current))
                {
                    return(false);
                }
            }

            return(true);
        }
Exemple #22
0
        public Backtracer(OptimizationContext context)
        {
            Context         = context;
            boundsCheckMemo = new List <BoundsCheckEntry>();
            charCheckMemo   = new List <CharCheckEntry>();

            while (boundsCheckMemo.Count < context.Instructions.Count)
            {
                boundsCheckMemo.Add(null);
                charCheckMemo.Add(null);
            }
        }
        private static int CheckEquality(OptimizationContext context, int refPoint, int refCount, int point)
        {
            for (var offset = 0; offset < refCount && point - offset >= 0; offset++)
            {
                if (context[refPoint - offset] != context[point - offset])
                {
                    return(offset);
                }
            }

            return(0);
        }
Exemple #24
0
        private static int GetNumChars(Instruction instruction, OptimizationContext context)
        {
            var numChars = 0;

            for (var i = instruction.Data1; i < instruction.Data2; i++)
            {
                var range = context.CharacterRanges[i];
                numChars += range.Max - range.Min + 1;
            }

            return(numChars);
        }
Exemple #25
0
        protected bool SequencesEqual(OptimizationContext context, int offset, Instruction[] neededInstructions)
        {
            for (var j = 0; j < neededInstructions.Length; j++)
            {
                if (context[offset + j] != neededInstructions[j])
                {
                    return(false);
                }
            }

            return(true);
        }
        private bool Unifies(OptimizationContext context, int leftOffset, int rightOffset, int length)
        {
            var labelMapping    = new Dictionary <ushort, ushort>();
            var variableMapping = new Dictionary <ushort, ushort>();

            for (var i = 0; i < length; i++)
            {
                var left  = context[leftOffset + i];
                var right = context[rightOffset + i];

                if (left.Type != right.Type ||
                    left.Data1 != right.Data1 ||
                    (left.Type != InstructionType.Call && right.Type != InstructionType.Call && left.Data2 != right.Data2) ||
                    left.Type == InstructionType.RestorePosition ||
                    left.Type == InstructionType.StorePosition ||
                    left.Type == InstructionType.MarkLabel)
                {
                    return(false);
                }

                if (left.Type != InstructionType.Call)
                {
                    if (!Unify(variableMapping, left.Label, right.Label))
                    {
                        return(false);
                    }
                }
                else
                {
                    var leftMapping  = context.FailureLabelMap[left.Data2];
                    var rightMapping = context.FailureLabelMap[right.Data2];
                    if (leftMapping.Mapping.Count != rightMapping.Mapping.Count)
                    {
                        return(false);
                    }

                    foreach (var(failureLabel, jumpTarget) in leftMapping.Mapping)
                    {
                        if (!rightMapping.TryGet(failureLabel, out var rightLabel))
                        {
                            return(false);
                        }

                        if (!Unify(variableMapping, jumpTarget, rightLabel))
                        {
                            return(false);
                        }
                    }
                }
            }

            return(true);
        }
Exemple #27
0
        public override ISqlPredicate ConvertSearchStringPredicate(MappingSchema mappingSchema, SqlPredicate.SearchString predicate,
                                                                   ConvertVisitor visitor,
                                                                   OptimizationContext optimizationContext)
        {
            if (!predicate.IgnoreCase)
            {
                return(ConvertSearchStringPredicateViaLike(mappingSchema, predicate, visitor, optimizationContext));
            }

            ISqlExpression expr;

            switch (predicate.Kind)
            {
            case SqlPredicate.SearchString.SearchKind.EndsWith:
            {
                predicate = new SqlPredicate.SearchString(
                    new SqlFunction(typeof(string), "$ToLower$", predicate.Expr1),
                    predicate.IsNot,
                    new SqlFunction(typeof(string), "$ToLower$", predicate.Expr2), predicate.Kind,
                    predicate.IgnoreCase);

                return(ConvertSearchStringPredicateViaLike(mappingSchema, predicate, visitor, optimizationContext));
            }

            case SqlPredicate.SearchString.SearchKind.StartsWith:
            {
                expr = new SqlExpression(typeof(bool),
                                         predicate.IsNot ? "{0} NOT STARTING WITH {1}" : "{0} STARTING WITH {1}",
                                         Precedence.Comparison,
                                         TryConvertToValue(predicate.Expr1, optimizationContext.Context), TryConvertToValue(predicate.Expr2, optimizationContext.Context))
                {
                    CanBeNull = false
                };
                break;
            }

            case SqlPredicate.SearchString.SearchKind.Contains:
                expr = new SqlExpression(typeof(bool),
                                         predicate.IsNot ? "{0} NOT CONTAINING {1}" : "{0} CONTAINING {1}",
                                         Precedence.Comparison,
                                         TryConvertToValue(predicate.Expr1, optimizationContext.Context), TryConvertToValue(predicate.Expr2, optimizationContext.Context))
                {
                    CanBeNull = false
                };
                break;

            default:
                throw new InvalidOperationException($"Unexpected predicate: {predicate.Kind}");
            }

            return(new SqlSearchCondition(new SqlCondition(false, new SqlPredicate.Expr(expr))));
        }
Exemple #28
0
        private void BuildOffsetInfo(OptimizationContext context, VariableOffset[] offsetInfo)
        {
            VariableOffset[] oldOffsetInfo;
            do
            {
                var labelPositions = CalculateLabelPositions(context);
                oldOffsetInfo = offsetInfo.Select(item => item.Clone()).ToArray();
                for (var i = 0; i < context.Count - 1; i++)
                {
                    var instruction = context[i];
                    var currentInfo = offsetInfo[i];
                    switch (instruction.Type)
                    {
                    case InstructionType.BoundsCheck:
                    case InstructionType.Char:
                        offsetInfo[labelPositions[instruction.Label]].UnionWith(currentInfo);
                        break;

                    case InstructionType.StorePosition:
                        currentInfo.DoStore(instruction.Data1);
                        break;

                    case InstructionType.Jump:
                        offsetInfo[labelPositions[instruction.Label]].UnionWith(currentInfo);
                        break;

                    case InstructionType.Call:
                        currentInfo.Invalidate();
                        foreach (var(_, jumpTarget) in context.FailureLabelMap[instruction.Data2].Mapping)
                        {
                            offsetInfo[labelPositions[jumpTarget]].UnionWith(currentInfo);
                        }
                        break;
                    }

                    if (instruction.Type != InstructionType.Jump)
                    {
                        switch (context[i + 1].Type)
                        {
                        case InstructionType.Advance:
                            offsetInfo[i + 1].UnionWith(currentInfo, (int)context[i + 1].Offset);
                            break;

                        default:
                            offsetInfo[i + 1].UnionWith(currentInfo);
                            break;
                        }
                    }
                }
            } while (!OffsetsAreEqual(offsetInfo, oldOffsetInfo));
        }
Exemple #29
0
 protected static IEnumerable <ushort> GetJumpTargets(OptimizationContext context, Instruction instruction)
 {
     if (instruction.CanJumpToLabel)
     {
         yield return(instruction.Label);
     }
     else if (instruction.Type == InstructionType.Call)
     {
         foreach (var kvp in context.FailureLabelMap[instruction.Data2].Mapping)
         {
             yield return(kvp.jumpTarget);
         }
     }
 }
Exemple #30
0
        private static bool ReindexLabels(OptimizationContext context, int[] labelsUsed, int[] labelMappings)
        {
            var reindexedLabels = new ushort[context.LabelAllocator];
            var numUsedLabels   = (ushort)0;

            for (var i = 0; i < labelsUsed.Length; i++)
            {
                if (labelsUsed[i] > 0 && labelMappings[i] == i)
                {
                    reindexedLabels[i] = numUsedLabels++;
                }
            }

            if (context.LabelAllocator != numUsedLabels)
            {
                for (var i = context.Count - 1; i >= 0; i--)
                {
                    var instruction = context[i];
                    switch (instruction.Type)
                    {
                    case InstructionType.Char:
                    case InstructionType.BoundsCheck:
                    case InstructionType.Jump:
                    case InstructionType.MarkLabel:
                        var newLabel = reindexedLabels[labelMappings[instruction.Label]];
                        if (i + 1 < context.Count && context[i + 1].Matches(InstructionType.MarkLabel, newLabel))
                        {
                            context.RemoveAt(i);
                        }
                        else
                        {
                            context[i] = context[i].WithLabel(newLabel);
                        }
                        break;
                    }
                }

                context.FailureLabelMap = context.FailureLabelMap
                                          .Select(map => new LabelMap(map
                                                                      .Mapping
                                                                      .Select(kvp => (kvp.failureLabel, reindexedLabels[labelMappings[kvp.jumpTarget]])))
                                                  )
                                          .ToList();
                context.LabelAllocator = numUsedLabels;
                context.ClearCache();
                return(true);
            }

            return(false);
        }