PreAllocatorCommon.cs 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. using ARMeilleure.IntermediateRepresentation;
  2. using System;
  3. using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
  4. namespace ARMeilleure.CodeGen
  5. {
  6. static class PreAllocatorCommon
  7. {
  8. public static void Propagate(ref Span<Operation> buffer, Operand dest, Operand value)
  9. {
  10. ReadOnlySpan<Operation> uses = dest.GetUses(ref buffer);
  11. foreach (Operation use in uses)
  12. {
  13. for (int srcIndex = 0; srcIndex < use.SourcesCount; srcIndex++)
  14. {
  15. Operand useSrc = use.GetSource(srcIndex);
  16. if (useSrc == dest)
  17. {
  18. use.SetSource(srcIndex, value);
  19. }
  20. else if (useSrc.Kind == OperandKind.Memory)
  21. {
  22. MemoryOperand memoryOp = useSrc.GetMemory();
  23. Operand baseAddr = memoryOp.BaseAddress;
  24. Operand index = memoryOp.Index;
  25. bool changed = false;
  26. if (baseAddr == dest)
  27. {
  28. baseAddr = value;
  29. changed = true;
  30. }
  31. if (index == dest)
  32. {
  33. index = value;
  34. changed = true;
  35. }
  36. if (changed)
  37. {
  38. use.SetSource(srcIndex, MemoryOp(
  39. useSrc.Type,
  40. baseAddr,
  41. index,
  42. memoryOp.Scale,
  43. memoryOp.Displacement));
  44. }
  45. }
  46. }
  47. }
  48. }
  49. }
  50. }