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