<commit_before>﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using Pchp.CodeAnalysis.Semantics;
using Pchp.CodeAnalysis.Semantics.Graph;
using Pchp.CodeAnalysis.Symbols;
using Peachpie.CodeAnalysis.Utilities;

namespace Pchp.CodeAnalysis.FlowAnalysis.Passes
{
    partial class TransformationRewriter
    {
        /// <summary>
        /// Each state in copy analysis maps each variable to a set of <see cref="BoundCopyValue"/> instances.
        /// Whenever a variable is modified, all the mapped copy operations are considered unavailable for removal
        /// due to the possible aliasing.
        /// </summary>
        private struct CopyAnalysisState
        {
            private BitMask[] _data;

            public CopyAnalysisState(int varCount)
            {
                _data = new BitMask[varCount];
            }

            public bool IsDefault => _data == null;

            public int VariableCount => _data.Length;

            public CopyAnalysisState Clone()
            {
                var clone = new CopyAnalysisState(_data.Length);
                _data.CopyTo(clone._data, 0);

                return clone;
            }

            public bool Equals(CopyAnalysisState other)
            {
                if (this.IsDefault != other.IsDefault)
                    return false;

                if ((this.IsDefault && other.IsDefault) || _data == other._data)
                    return true;

                // We are supposed to compare only states from the same routine
                Debug.Assert(_data.Length == other._data.Length);

                for (int i = 0; i < other._data.Length; i++)
                {
                    if (_data[i] != other._data[i])
                        return false;
                }

                return true;
            }

            public BitMask GetValue(int varIndex) => _data[varIndex];

            public CopyAnalysisState WithMerge(CopyAnalysisState other)
            {
                if (this.IsDefault)
                    return other;
                else if (other.IsDefault)
                    return this;

                if (this.Equals(other))
                {
                    return this;
                }

                var merged = new CopyAnalysisState(_data.Length);
                for (int i = 0; i < merged._data.Length; i++)
                {
                    merged._data[i] = _data[i] | other._data[i];
                }

                return merged;
            }

            public CopyAnalysisState WithValue(int varIndex, BitMask value)
            {
                Debug.Assert(!IsDefault);

                if (_data[varIndex] == value)
                {
                    return this;
                }
                else
                {
                    var result = Clone();
                    result._data[varIndex] = value;
                    return result;
                }
            }

            public CopyAnalysisState WithCopyAssignment(int trgVarIndex, int srcVarIndex, int copyIndex)
            {
                Debug.Assert(!IsDefault);

                var copyMask = BitMask.FromSingleValue(copyIndex);

                if (_data[trgVarIndex] != copyMask || _data[srcVarIndex] != (_data[srcVarIndex] | copyMask))
                {
                    var result = Clone();
                    result._data[trgVarIndex] = copyMask;
                    result._data[srcVarIndex] |= copyMask;
                    return result;
                }
                else
                {
                    return this;
                }
            }
        }

        /// <summary>
        /// Implements copy analysis using <see cref="CopyAnalysisState"/>, producing a set of <see cref="BoundCopyValue"/>
        /// instances available for removal.
        /// </summary>
        private class CopyAnalysisContext : SingleBlockWalker<VoidStruct>, IFixPointAnalysisContext<CopyAnalysisState>
        {
            private readonly Dictionary<BoundCopyValue, int> _copyIndices = new Dictionary<BoundCopyValue, int>();
            private readonly FlowContext _flowContext;

            /// <summary>
            /// Set of <see cref="BoundCopyValue"/> instances located in return statements, to be filtered in the exit node.
            /// </summary>
            private HashSet<BoundCopyValue> _lazyReturnCopies;
<commit_msg>Rename CopyAnalysisState._data to _varState<commit_after>﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using Pchp.CodeAnalysis.Semantics;
using Pchp.CodeAnalysis.Semantics.Graph;
using Pchp.CodeAnalysis.Symbols;
using Peachpie.CodeAnalysis.Utilities;

namespace Pchp.CodeAnalysis.FlowAnalysis.Passes
{
    partial class TransformationRewriter
    {
        /// <summary>
        /// Each state in copy analysis maps each variable to a set of <see cref="BoundCopyValue"/> instances.
        /// Whenever a variable is modified, all the mapped copy operations are considered unavailable for removal
        /// due to the possible aliasing.
        /// </summary>
        private struct CopyAnalysisState
        {
            private BitMask[] _varState;

            public CopyAnalysisState(int varCount)
            {
                _varState = new BitMask[varCount];
            }

            public bool IsDefault => _varState == null;

            public int VariableCount => _varState.Length;

            public CopyAnalysisState Clone()
            {
                var clone = new CopyAnalysisState(_varState.Length);
                _varState.CopyTo(clone._varState, 0);

                return clone;
            }

            public bool Equals(CopyAnalysisState other)
            {
                if (this.IsDefault != other.IsDefault)
                    return false;

                if ((this.IsDefault && other.IsDefault) || _varState == other._varState)
                    return true;

                // We are supposed to compare only states from the same routine
                Debug.Assert(_varState.Length == other._varState.Length);

                for (int i = 0; i < other._varState.Length; i++)
                {
                    if (_varState[i] != other._varState[i])
                        return false;
                }

                return true;
            }

            public BitMask GetValue(int varIndex) => _varState[varIndex];

            public CopyAnalysisState WithMerge(CopyAnalysisState other)
            {
                if (this.IsDefault)
                    return other;
                else if (other.IsDefault)
                    return this;

                if (this.Equals(other))
                {
                    return this;
                }

                var merged = new CopyAnalysisState(_varState.Length);
                for (int i = 0; i < merged._varState.Length; i++)
                {
                    merged._varState[i] = _varState[i] | other._varState[i];
                }

                return merged;
            }

            public CopyAnalysisState WithValue(int varIndex, BitMask value)
            {
                Debug.Assert(!IsDefault);

                if (_varState[varIndex] == value)
                {
                    return this;
                }
                else
                {
                    var result = Clone();
                    result._varState[varIndex] = value;
                    return result;
                }
            }

            public CopyAnalysisState WithCopyAssignment(int trgVarIndex, int srcVarIndex, int copyIndex)
            {
                Debug.Assert(!IsDefault);

                var copyMask = BitMask.FromSingleValue(copyIndex);

                if (_varState[trgVarIndex] != copyMask || _varState[srcVarIndex] != (_varState[srcVarIndex] | copyMask))
                {
                    var result = Clone();
                    result._varState[trgVarIndex] = copyMask;
                    result._varState[srcVarIndex] |= copyMask;
                    return result;
                }
                else
                {
                    return this;
                }
            }
        }

        /// <summary>
        /// Implements copy analysis using <see cref="CopyAnalysisState"/>, producing a set of <see cref="BoundCopyValue"/>
        /// instances available for removal.
        /// </summary>
        private class CopyAnalysisContext : SingleBlockWalker<VoidStruct>, IFixPointAnalysisContext<CopyAnalysisState>
        {
            private readonly Dictionary<BoundCopyValue, int> _copyIndices = new Dictionary<BoundCopyValue, int>();
            private readonly FlowContext _flowContext;

            /// <summary>
            /// Set of <see cref="BoundCopyValue"/> instances located in return statements, to be filtered in the exit node.
            /// </summary>
            private HashSet<BoundCopyValue> _lazyReturnCopies;

{'fraction_non_alphanumeric': 0.08219026548672566, 'fraction_numerical': 0.000663716814159292, 'mean_word_length': 1.4232109354060574, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7253747', 'n_tokens_mistral': 2220, 'n_tokens_neox': 2059, 'n_words': 557}