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() })
private static IEnumerable <string> ConstructResult( IReadOnlyList <CodeBlock> instructionSequence, RegisterAllocationResult allocation, Function function) { var usefulLabels = new HashSet <string>(UsefulLabels(instructionSequence)); return(new[] { $"section .data", $"{function.LayoutLabel}:" } .Concat(function.GenerateStackLayout()) .Concat(new[] { $"section .text", $"{function.MangledName}:" }) .Concat(instructionSequence.SelectMany(codeBlock => { var ret = codeBlock.Instructions.SelectMany(instruction => instruction.ToASM(allocation.Allocation)); return !usefulLabels.Contains(codeBlock.Label.Id) ? ret : ret.Prepend($"{codeBlock.Label.Id}:"); }))); }