private static List <string> CheckResult( InterferenceCopyGraphPair query, IEnumerable <HardwareRegister> allowedHardwareRegisters, RegisterAllocationResult result) { var interference = query.InterferenceGraph; var registerMapping = result.Allocation; var spilled = result.Spilled; var notAllowedHardwareRegisterUse = HardwareRegister.Values .Where(register => !allowedHardwareRegisters.Contains(register)) .Select(register => new { Register = register, Mapping = registerMapping .Where(x => x.Key != register && x.Value == register) .Select(x => x.Key) .ToList() }) .Where(x => x.Mapping.Any()) .Select(failedRegister => { var mappingsText = string.Join(", ", failedRegister.Mapping); return ($"Hardware register '{failedRegister.Register}' is not allowed but used for {{{mappingsText}}}."); }); var notMappedHardwareRegisters = HardwareRegister.Values .Where(register => !registerMapping.ContainsKey(register)) .Select(register => $"Hardware register '{register}' not mapped."); var incorrectlyMappedHardwareRegisters = HardwareRegister.Values .Where(register => registerMapping.ContainsKey(register)) .Select(register => new { Register = registerMapping[register], Mapping = register }) .Where(register => register.Register != register.Mapping) .Select(register => $"Hardware register '{register.Register}' not mapped to itself but to {register.Mapping}."); var notMappedRegistersFromInterference = interference.Keys .Where(register => !(registerMapping.ContainsKey(register) || spilled.Contains(register))) .Select(register => $"Register '{register}' from interference not mapped or spilled."); var bothMappedAndSpilled = spilled .Where(registerMapping.ContainsKey) .Select(register => $"Register '{register}' both mapped and spilled."); var conflictingRegisters = interference .Where(register => registerMapping.ContainsKey(register.Key)) .Select(mapping => new { Register = mapping.Key, Conflicts = mapping.Value .Where(y => registerMapping.TryGetValue(y, out var yMapping) && registerMapping[mapping.Key] == yMapping) .ToList() })
internal static List <VirtualRegister> GetAllRegisters(this InterferenceCopyGraphPair query) { return(new HashSet <VirtualRegister>( query.InterferenceGraph.Keys .Concat(query.CopyGraph.Keys) .Concat(HardwareRegister.Values)) .ToList()); }
public RegisterAllocationResult Allocate( InterferenceCopyGraphPair query, IReadOnlyCollection <HardwareRegister> allowedHardwareRegisters) { var allowedRegistersCount = allowedHardwareRegisters.Count; query = new InterferenceCopyGraphPair( query.InterferenceGraph, RemoveUnavailableHWRegisters(query.CopyGraph, allowedHardwareRegisters)); var allRegisters = query.GetAllRegisters(); var superVertices = allRegisters .ToDictionary( x => x, x => new HashSet <VirtualRegister> { x }); var interference = RegisterAllocatorUtils.GetGraph(allRegisters, superVertices, query.InterferenceGraph); interference.AddHardwareRegisterClique(superVertices); var copy = RegisterAllocatorUtils.GetGraph(allRegisters, superVertices, query.CopyGraph); var coalescingProcess = new CoalescingProcess(interference, copy, superVertices, allowedRegistersCount); var registerSorter = new RegisterSorter( interference, copy, superVertices, allRegisters, coalescingProcess, allowedHardwareRegisters.Count); var order = registerSorter.GetOrder().ToList(); var verticesEnumerable = allRegisters.Select(register => superVertices[register]); var vertices = new HashSet <HashSet <VirtualRegister> >(verticesEnumerable); var finalInterference = FinalGraph(allRegisters, superVertices, query.InterferenceGraph); var finalCopy = FinalGraph(allRegisters, superVertices, query.CopyGraph); var registerPainter = new RegisterPainter(finalInterference, finalCopy, superVertices); return(registerPainter.GetColoring(vertices, allowedHardwareRegisters, order, allRegisters)); }