private static List <int> GetAllInvariantInstructions(MetaMidRepresentation intermediateCode, int loopStart,
                                                              int loopEnd, HashSet <LocalVariable> getAllDefinedVariables)
        {
            var useDef   = intermediateCode.UseDef;
            var localOps = useDef.GetLocalOperations();


            var result = new List <int>();

            for (var index = loopStart; index <= loopEnd; index++)
            {
                var op = localOps[index];
                switch (op.Kind)
                {
                default:
                    continue;

                case OperationKind.UnaryOperator:
                case OperationKind.Call:
                case OperationKind.BinaryOperator:
                case OperationKind.GetField:
                case OperationKind.Assignment:
                    break;
                }
                if (op.Kind == OperationKind.Call)
                {
                    var methodData = EvaluatePureFunctionWithConstantCall.ComputeAndEvaluatePurityOfCall(op);
                    if (!methodData.Interpreter.AnalyzeProperties.IsPure)
                    {
                        continue;
                    }
                }
                var usages      = useDef.GetUsages(index);
                var isInvariant = true;
                foreach (var usage in usages)
                {
                    if (!getAllDefinedVariables.Contains(usage))
                    {
                        continue;
                    }
                    isInvariant = false;
                    break;
                }
                if (!isInvariant)
                {
                    continue;
                }
                result.Add(index);
            }

            return(result);
        }
        public static List <int> FindCallsToPureFunctions(UseDefDescription useDef, int startRange, int endRange)
        {
            var calls   = new List <int>();
            var opArr   = useDef.GetLocalOperations();
            var callIds = useDef.GetOperationsOfKind(OperationKind.Call);

            foreach (var index in callIds)
            {
                if (index < startRange || index > endRange)
                {
                    continue;
                }
                var operation     = opArr[index];
                var operationData = EvaluatePureFunctionWithConstantCall.ComputeAndEvaluatePurityOfCall(operation);
                if (!operationData.Interpreter.AnalyzeProperties.IsPure || !operationData.Info.IsStatic)
                {
                    continue;
                }
                calls.Add(index);
            }
            return(calls);
        }