ARMMacroFusion.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. //===- ARMMacroFusion.cpp - ARM Macro Fusion ----------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. /// \file This file contains the ARM implementation of the DAG scheduling
  10. /// mutation to pair instructions back to back.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "ARMMacroFusion.h"
  14. #include "ARMSubtarget.h"
  15. #include "llvm/CodeGen/MacroFusion.h"
  16. #include "llvm/CodeGen/TargetInstrInfo.h"
  17. namespace llvm {
  18. // Fuse AES crypto encoding or decoding.
  19. static bool isAESPair(const MachineInstr *FirstMI,
  20. const MachineInstr &SecondMI) {
  21. // Assume the 1st instr to be a wildcard if it is unspecified.
  22. switch(SecondMI.getOpcode()) {
  23. // AES encode.
  24. case ARM::AESMC :
  25. return FirstMI == nullptr || FirstMI->getOpcode() == ARM::AESE;
  26. // AES decode.
  27. case ARM::AESIMC:
  28. return FirstMI == nullptr || FirstMI->getOpcode() == ARM::AESD;
  29. }
  30. return false;
  31. }
  32. // Fuse literal generation.
  33. static bool isLiteralsPair(const MachineInstr *FirstMI,
  34. const MachineInstr &SecondMI) {
  35. // Assume the 1st instr to be a wildcard if it is unspecified.
  36. if ((FirstMI == nullptr || FirstMI->getOpcode() == ARM::MOVi16) &&
  37. SecondMI.getOpcode() == ARM::MOVTi16)
  38. return true;
  39. return false;
  40. }
  41. /// Check if the instr pair, FirstMI and SecondMI, should be fused
  42. /// together. Given SecondMI, when FirstMI is unspecified, then check if
  43. /// SecondMI may be part of a fused pair at all.
  44. static bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
  45. const TargetSubtargetInfo &TSI,
  46. const MachineInstr *FirstMI,
  47. const MachineInstr &SecondMI) {
  48. const ARMSubtarget &ST = static_cast<const ARMSubtarget&>(TSI);
  49. if (ST.hasFuseAES() && isAESPair(FirstMI, SecondMI))
  50. return true;
  51. if (ST.hasFuseLiterals() && isLiteralsPair(FirstMI, SecondMI))
  52. return true;
  53. return false;
  54. }
  55. std::unique_ptr<ScheduleDAGMutation> createARMMacroFusionDAGMutation () {
  56. return createMacroFusionDAGMutation(shouldScheduleAdjacent);
  57. }
  58. } // end namespace llvm