/// <summary> /// Creates a RegisterLiveness for an output register /// </summary> /// <param name="nRegister"></param> /// <param name="transformed_from"></param> public RegisterLiveness(int nRegister, RegisterLiveness transformed_from) { NumRegister = nRegister; FromInstruction = -9999;// transformed_from.FromInstruction; ToInstruction = -9999;// transformed_from.ToInstruction; transformed_from.Transformed = this; TransformedFrom = new List<RegisterLiveness>(); TransformedFrom.Add(transformed_from); }
/// <summary> /// Update the liveness for a given register, to include this instruction /// </summary> /// <param name="dict"></param> /// <param name="nRegister"></param> /// <param name="at_instruction"></param> /// <returns></returns> RegisterLiveness TouchRegister(Dictionary<int, RegisterLiveness> dict, int nRegister, int at_instruction) { RegisterLiveness rl; if (!dict.TryGetValue(nRegister, out rl)) { rl = new RegisterLiveness(nRegister, at_instruction); dict[nRegister] = rl; return rl; } rl.Touch(at_instruction); return rl; }
/// <summary> /// Selects an output register number, given an input register number /// An improved implementation might be more picky about the selection, this one grabs the next available off a stack. /// </summary> /// <param name="nInputRegister"></param> /// <param name="nInstruction"></param> /// <returns></returns> int GetOutputRegister(int nInputRegister, int nInstruction) { RegisterLiveness irl = InputRegisters[nInputRegister]; if (irl.Transformed != null) return irl.Transformed.NumRegister; int nOutputRegister = Derp.GetOutputRegister(nInputRegister,this); RegisterLiveness rl; if (OutputRegisters.TryGetValue(nOutputRegister, out rl)) { rl.Touch(nInstruction); irl.Transformed = rl; rl.TransformedFrom.Add(irl); } else { rl = new RegisterLiveness(nOutputRegister, irl); rl.Touch(nInstruction); OutputRegisters.Add(nOutputRegister, rl); } return nOutputRegister; }
public bool Intersects(RegisterLiveness other) { if (other.FromInstruction >= ToInstruction) return false; if (FromInstruction >= other.ToInstruction) return false; return true; }
public void Dispose() { _Transformed = null; if (TransformedFrom != null) { TransformedFrom.Clear(); TransformedFrom = null; } }
/// <summary> /// Creates a RegisterLiveness for an output register /// </summary> /// <param name="nRegister"></param> /// <param name="transformed_from"></param> public RegisterLiveness(int nRegister, RegisterLiveness transformed_from) { NumRegister = nRegister; Transformed = transformed_from; }
/// <summary> /// Selects an output register number, given an input register number /// An improved implementation might be more picky about the selection, this one grabs the next available off a stack. /// </summary> /// <param name="nInputRegister"></param> /// <param name="nInstruction"></param> /// <returns></returns> int GetOutputRegister(int nInputRegister, int nInstruction) { // see if it's already transformed RegisterLiveness input = InputRegisters[nInputRegister]; RegisterLiveness transformed = input.Transformed; if (transformed != null) return transformed.NumRegister; // not already transformed, pick an available register if (AvailableRegisters.Count == 0) { throw new NotImplementedException("Out of registers!"); } int nOutputRegister = AvailableRegisters.Pop(); // are we reusing a register? if (!OutputRegisters.TryGetValue(nOutputRegister, out transformed)) { transformed = new RegisterLiveness(nOutputRegister, input); OutputRegisters[nOutputRegister] = transformed; } input.Transformed = transformed; UnavailableRegisters.Add(transformed); return nOutputRegister; }