X86MacroFusion.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. //===- X86MacroFusion.cpp - X86 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 X86 implementation of the DAG scheduling
  10. /// mutation to pair instructions back to back.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "X86MacroFusion.h"
  14. #include "MCTargetDesc/X86BaseInfo.h"
  15. #include "X86Subtarget.h"
  16. #include "llvm/CodeGen/MacroFusion.h"
  17. #include "llvm/CodeGen/ScheduleDAGMutation.h"
  18. #include "llvm/CodeGen/TargetInstrInfo.h"
  19. using namespace llvm;
  20. static X86::FirstMacroFusionInstKind classifyFirst(const MachineInstr &MI) {
  21. return X86::classifyFirstOpcodeInMacroFusion(MI.getOpcode());
  22. }
  23. static X86::SecondMacroFusionInstKind classifySecond(const MachineInstr &MI) {
  24. X86::CondCode CC = X86::getCondFromBranch(MI);
  25. return X86::classifySecondCondCodeInMacroFusion(CC);
  26. }
  27. /// Check if the instr pair, FirstMI and SecondMI, should be fused
  28. /// together. Given SecondMI, when FirstMI is unspecified, then check if
  29. /// SecondMI may be part of a fused pair at all.
  30. static bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
  31. const TargetSubtargetInfo &TSI,
  32. const MachineInstr *FirstMI,
  33. const MachineInstr &SecondMI) {
  34. const X86Subtarget &ST = static_cast<const X86Subtarget &>(TSI);
  35. // Check if this processor supports any kind of fusion.
  36. if (!(ST.hasBranchFusion() || ST.hasMacroFusion()))
  37. return false;
  38. const X86::SecondMacroFusionInstKind BranchKind = classifySecond(SecondMI);
  39. if (BranchKind == X86::SecondMacroFusionInstKind::Invalid)
  40. return false; // Second cannot be fused with anything.
  41. if (FirstMI == nullptr)
  42. return true; // We're only checking whether Second can be fused at all.
  43. const X86::FirstMacroFusionInstKind TestKind = classifyFirst(*FirstMI);
  44. if (ST.hasBranchFusion()) {
  45. // Branch fusion can merge CMP and TEST with all conditional jumps.
  46. return (TestKind == X86::FirstMacroFusionInstKind::Cmp ||
  47. TestKind == X86::FirstMacroFusionInstKind::Test);
  48. }
  49. if (ST.hasMacroFusion()) {
  50. return X86::isMacroFused(TestKind, BranchKind);
  51. }
  52. llvm_unreachable("unknown fusion type");
  53. }
  54. namespace llvm {
  55. std::unique_ptr<ScheduleDAGMutation>
  56. createX86MacroFusionDAGMutation () {
  57. return createBranchMacroFusionDAGMutation(shouldScheduleAdjacent);
  58. }
  59. } // end namespace llvm