private int GuessSpill(RegisterClass @class, VariableData vd, int allocableRegs) { if (allocableRegs == 0) { throw new ArgumentException(); } return(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; }
public void RegisterContextVariable(VariableData vd) { if (vd.LocalId != Constants.InvalidId) { return; } vd.LocalId = ContextVd.Count; ContextVd.Add(vd); }
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); }
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); }
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); }
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); } }
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); }
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); }