Пример #1
0
 private int GuessSpill(RegisterClass @class, VariableData vd, int allocableRegs)
 {
     if (allocableRegs == 0)
     {
         throw new ArgumentException();
     }
     return(0);
 }
Пример #2
0
 public void Setup(VariableData vd, VariableFlags flags = 0, int inRegs = 0, int allocableRegs = 0)
 {
     VariableData  = vd;
     Flags         = flags;
     UsageCount    = 0;
     InRegIndex    = RegisterIndex.Invalid;
     OutRegIndex   = RegisterIndex.Invalid;
     InRegs        = inRegs;
     AllocableRegs = allocableRegs;
 }
Пример #3
0
        public void RegisterContextVariable(VariableData vd)
        {
            if (vd.LocalId != Constants.InvalidId)
            {
                return;
            }

            vd.LocalId = ContextVd.Count;
            ContextVd.Add(vd);
        }
Пример #4
0
        public VariableAttributes Add(VariableData vd, VariableFlags flags, int newAllocable)
        {
            var va = _tmpList[VariableCount++];

            va.Setup(vd, flags, 0, newAllocable);
            va.UsageCount += 1;
            vd.Attributes  = va;

            RegisterContextVariable(vd);
            RegCount.Add(vd.Info.RegisterClass);
            return(va);
        }
Пример #5
0
        public VariableAttributes FindAttributesByClass(RegisterClass @class, VariableData vd)
        {
            var list  = GetListByClass(@class);
            var count = Count.Get(@class);

            for (var i = 0; i < count; i++)
            {
                if (list[i].VariableData == vd)
                {
                    return(list[i]);
                }
            }
            return(null);
        }
Пример #6
0
        public VariableAttributes FindAttributes(VariableData vd)
        {
            var list  = Attributes;
            var count = AttributesCount;

            for (var i = 0; i < count; i++)
            {
                if (list[i].VariableData == vd)
                {
                    return(list[i]);
                }
            }
            return(null);
        }
Пример #7
0
        private void InsertCallArgument(CallNode call, VariableData sVd, FunctionInOut arg, int argIndex, ref SArgData[] sArgList, ref int sArgCount)
        {
            int i;

            var aType = arg.VariableType;
            var sType = sVd.Type;

            // First locate or create sArgBase.
            for (i = 0; i < sArgCount; i++)
            {
                if (sArgList[i].Svd == sVd && sArgList[i].Cvd == null)
                {
                    break;
                }
            }

            var sArgData = sArgList[i];

            if (i == sArgCount)
            {
                sArgData.Svd  = sVd;
                sArgData.Cvd  = null;
                sArgData.Arg  = null;
                sArgData.Type = VariableType.Invalid;
                sArgCount++;
            }

            var sInfo  = sType.GetVariableInfo();
            var sClass = sInfo.RegisterClass;

            if (SArgData.MustConvertSArg(aType, sType))
            {
                var cType  = SArgData.TypeOfConvertedSArg(aType, sType);
                var cInfo  = cType.GetVariableInfo();
                var cClass = cInfo.RegisterClass;
                while (++i < sArgCount)
                {
                    sArgData = sArgList[i];
                    if (sArgData.Svd != sVd)
                    {
                        break;
                    }

                    if (sArgData.Cvd.Type != cType || sArgData.Type != aType)
                    {
                        continue;
                    }

                    sArgData.Arg.AffectedArguments |= Utils.Mask(argIndex);
                    return;
                }

                var cVd  = _compiler.CreateVariableData(cType, cInfo, null);
                var sArg = new CallArgumentNode(call, sVd, cVd);
                var map  = new VariableMap(2);

                _variableContext.RegisterContextVariable(cVd);
                _variableContext.RegisterContextVariable(sVd);

                map.Count.Add(sClass);
                map.Count.Add(cClass);

                if (sClass <= cClass)
                {
                    map.Attributes[0].Setup(sVd, VariableFlags.RReg, 0, _variableContext.GaRegs[sClass]);
                    map.Attributes[1].Setup(cVd, VariableFlags.WReg, 0, _variableContext.GaRegs[cClass]);
                    map.Start.Set(cClass, (sClass != cClass).AsInt());
                }
                else
                {
                    map.Attributes[0].Setup(cVd, VariableFlags.WReg, 0, _variableContext.GaRegs[cClass]);
                    map.Attributes[1].Setup(sVd, VariableFlags.RReg, 0, _variableContext.GaRegs[sClass]);
                    map.Start.Set(sClass, 1);
                }

                sArg.VariableMap        = map;
                sArg.AffectedArguments |= Utils.Mask(argIndex);

                _compiler.AddNodeBefore(sArg, call);
                //::memmove(sArgData + 1, sArgData, (sArgCount - i) * sizeof(SArgData));

                var tmp = new SArgData[sArgCount + 1];
                Array.Copy(sArgList, 0, tmp, 0, i);
                Array.Copy(sArgList, i + 1, tmp, i + 1, sArgCount - i);

                sArgList = tmp;

                sArgData.Svd  = sVd;
                sArgData.Cvd  = cVd;
                sArgData.Arg  = sArg;
                sArgData.Type = aType;

                sArgCount++;
            }
            else
            {
                var sArg = sArgData.Arg;
                _variableContext.RegisterContextVariable(sVd);

                if (sArg == null)
                {
                    sArg = new CallArgumentNode(call, sVd, null);

                    var map = new VariableMap(1);

                    map.Count.Add(sClass);
                    map.Attributes[0].Setup(sVd, VariableFlags.RReg, 0, _variableContext.GaRegs[sClass]);

                    sArg.VariableMap = map;
                    sArgData.Arg     = sArg;

                    _compiler.AddNodeBefore(sArg, call);
                }

                sArg.AffectedArguments |= Utils.Mask(argIndex);
            }
        }
Пример #8
0
        private int GuessAlloc(RegisterClass @class, VariableData vd, int allocableRegs)
        {
            if (allocableRegs == 0)
            {
                throw new ArgumentException();
            }
            if (allocableRegs.IsPowerOf2())
            {
                return(allocableRegs);
            }

            var safeRegs = allocableRegs;
            var node     = Node;

            for (var j = 0; j < Assembler.MaxLookAhead; j++)
            {
                if (node.Flags.IsSet(CodeNodeFlags.Ret) || node.Flags.IsSet(CodeNodeFlags.Jcc))
                {
                    break;
                }
                if (node.Flags.IsSet(CodeNodeFlags.Jmp))
                {
                    node = node.As <JumpNode>().Target;
                    if (node == null)
                    {
                        break;
                    }
                }
                node = node.Next;
                if (node == null)
                {
                    throw new ArgumentException();
                }
                var map = node.VariableMap;
                if (map == null)
                {
                    continue;
                }
                var va = map.FindAttributesByClass(@class, vd);
                if (va != null)
                {
                    var inRegs = va.InRegs;
                    if (inRegs != 0)
                    {
                        safeRegs       = allocableRegs;
                        allocableRegs &= inRegs;

                        return(allocableRegs == 0 ? safeRegs : allocableRegs);
                    }
                }

                safeRegs       = allocableRegs;
                allocableRegs &= ~(map.InRegs.Get(@class) | map.OutRegs.Get(@class) | map.ClobberedRegs.Get(@class));

                if (allocableRegs == 0)
                {
                    break;
                }
            }
            return(safeRegs);
        }
Пример #9
0
        private int GuessAlloc(VariableData vd, int allocableRegs, RegisterClass @class)
        {
            if (!(allocableRegs != 0))
            {
                throw new ArgumentException();
            }

            if (allocableRegs.IsPowerOf2())
            {
                return(allocableRegs);
            }

            var safeRegs = allocableRegs;
            var localId  = vd.LocalId;
            var node     = Node;

            for (var i = 0; i < Assembler.MaxLookAhead; i++)
            {
                var liveness = node.Liveness;

                // If the variable becomes dead it doesn't make sense to continue.
                if (liveness != null && liveness.GetBit(localId) == 0)
                {
                    break;
                }

                // Stop on `HLSentinel` and `HLRet`.
                if (node.Flags.IsSet(CodeNodeFlags.Ret))
                {
                    break;
                }

                // Stop on conditional jump, we don't follow them.
                if (node.Flags.IsSet(CodeNodeFlags.Jcc))
                {
                    break;
                }

                // Advance on non-conditional jump.
                if (node.Flags.IsSet(CodeNodeFlags.Jmp))
                {
                    node = node.As <JumpNode>().Target;
                    // Stop on jump that is not followed.
                    if (node == null)
                    {
                        break;
                    }
                }

                node = node.Next;
                if (node == null)
                {
                    throw new ArgumentException();
                }

                var map = node.VariableMap;
                if (map == null)
                {
                    continue;
                }
                var va = map.FindAttributesByClass(@class, vd);

                if (va != null)
                {
                    // If the variable is overwritten it doesn't mase sense to continue.
                    if ((va.Flags & VariableFlags.RAll) == 0)
                    {
                        break;
                    }

                    var mask = va.AllocableRegs;
                    if (mask != 0)
                    {
                        allocableRegs &= mask;
                        if (allocableRegs == 0)
                        {
                            break;
                        }
                        safeRegs = allocableRegs;
                    }

                    mask = va.InRegs;
                    if (mask != 0)
                    {
                        allocableRegs &= mask;
                        if (allocableRegs == 0)
                        {
                            break;
                        }
                        safeRegs = allocableRegs;
                        break;
                    }

                    allocableRegs &= ~(map.OutRegs.Get(@class) | map.ClobberedRegs.Get(@class));
                    if (allocableRegs == 0)
                    {
                        break;
                    }
                }
                else
                {
                    allocableRegs &= ~(map.InRegs.Get(@class) | map.OutRegs.Get(@class) | map.ClobberedRegs.Get(@class));
                    if (allocableRegs == 0)
                    {
                        break;
                    }
                }

                safeRegs = allocableRegs;
            }
            return(safeRegs);
        }