X86MacroFusion.cpp 2.6 KB

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