BlockPlacement.cs 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. using ARMeilleure.IntermediateRepresentation;
  2. using ARMeilleure.Translation;
  3. using System.Diagnostics;
  4. using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
  5. namespace ARMeilleure.CodeGen.Optimizations
  6. {
  7. static class BlockPlacement
  8. {
  9. public static void RunPass(ControlFlowGraph cfg)
  10. {
  11. bool update = false;
  12. BasicBlock block;
  13. BasicBlock nextBlock;
  14. BasicBlock lastBlock = cfg.Blocks.Last;
  15. // Move cold blocks at the end of the list, so that they are emitted away from hot code.
  16. for (block = cfg.Blocks.First; block != null; block = nextBlock)
  17. {
  18. nextBlock = block.ListNext;
  19. if (block.Frequency == BasicBlockFrequency.Cold)
  20. {
  21. cfg.Blocks.Remove(block);
  22. cfg.Blocks.AddLast(block);
  23. }
  24. if (block == lastBlock)
  25. {
  26. break;
  27. }
  28. }
  29. for (block = cfg.Blocks.First; block != null; block = nextBlock)
  30. {
  31. nextBlock = block.ListNext;
  32. if (block.SuccessorsCount == 2)
  33. {
  34. Operation branchOp = block.Operations.Last;
  35. Debug.Assert(branchOp.Instruction == Instruction.BranchIf);
  36. BasicBlock falseSucc = block.GetSuccessor(0);
  37. BasicBlock trueSucc = block.GetSuccessor(1);
  38. // If true successor is next block in list, invert the condition. We avoid extra branching by
  39. // making the true side the fallthrough (i.e, convert it to the false side).
  40. if (trueSucc == block.ListNext)
  41. {
  42. Comparison comp = (Comparison)branchOp.GetSource(2).AsInt32();
  43. Comparison compInv = comp.Invert();
  44. branchOp.SetSource(2, Const((int)compInv));
  45. block.SetSuccessor(0, trueSucc);
  46. block.SetSuccessor(1, falseSucc);
  47. update = true;
  48. }
  49. }
  50. }
  51. if (update)
  52. {
  53. cfg.Update();
  54. }
  55. }
  56. }
  57. }