BlockPlacement.cs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. using ARMeilleure.IntermediateRepresentation;
  2. using ARMeilleure.Translation;
  3. using System.Diagnostics;
  4. using static ARMeilleure.IntermediateRepresentation.OperandHelper;
  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 != lastBlock; 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. }
  25. for (block = cfg.Blocks.First; block != null; block = nextBlock)
  26. {
  27. nextBlock = block.ListNext;
  28. if (block.SuccessorCount == 2 && block.Operations.Last is Operation branchOp)
  29. {
  30. Debug.Assert(branchOp.Instruction == Instruction.BranchIf);
  31. BasicBlock falseSucc = block.GetSuccessor(0);
  32. BasicBlock trueSucc = block.GetSuccessor(1);
  33. // If true successor is next block in list, invert the condition. We avoid extra branching by
  34. // making the true side the fallthrough (i.e, convert it to the false side).
  35. if (trueSucc == block.ListNext)
  36. {
  37. Comparison comp = (Comparison)branchOp.GetSource(2).AsInt32();
  38. Comparison compInv = comp.Invert();
  39. branchOp.SetSource(2, Const((int)compInv));
  40. block.SetSuccessor(0, trueSucc);
  41. block.SetSuccessor(1, falseSucc);
  42. update = true;
  43. }
  44. }
  45. }
  46. if (update)
  47. {
  48. cfg.Update(removeUnreachableBlocks: false);
  49. }
  50. }
  51. }
  52. }