Home | History | Annotate | Line # | Download | only in X86
      1      1.1  joerg //===- X86MacroFusion.cpp - X86 Macro Fusion ------------------------------===//
      2      1.1  joerg //
      3      1.1  joerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4      1.1  joerg // See https://llvm.org/LICENSE.txt for license information.
      5      1.1  joerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6      1.1  joerg //
      7      1.1  joerg //===----------------------------------------------------------------------===//
      8      1.1  joerg //
      9      1.1  joerg /// \file This file contains the X86 implementation of the DAG scheduling
     10      1.1  joerg /// mutation to pair instructions back to back.
     11      1.1  joerg //
     12      1.1  joerg //===----------------------------------------------------------------------===//
     13      1.1  joerg 
     14      1.1  joerg #include "X86MacroFusion.h"
     15  1.1.1.2  joerg #include "MCTargetDesc/X86BaseInfo.h"
     16      1.1  joerg #include "X86Subtarget.h"
     17      1.1  joerg #include "llvm/CodeGen/MacroFusion.h"
     18      1.1  joerg #include "llvm/CodeGen/TargetInstrInfo.h"
     19      1.1  joerg 
     20      1.1  joerg using namespace llvm;
     21      1.1  joerg 
     22  1.1.1.2  joerg static X86::FirstMacroFusionInstKind classifyFirst(const MachineInstr &MI) {
     23  1.1.1.2  joerg   return X86::classifyFirstOpcodeInMacroFusion(MI.getOpcode());
     24      1.1  joerg }
     25      1.1  joerg 
     26  1.1.1.2  joerg static X86::SecondMacroFusionInstKind classifySecond(const MachineInstr &MI) {
     27      1.1  joerg   X86::CondCode CC = X86::getCondFromBranch(MI);
     28  1.1.1.2  joerg   return X86::classifySecondCondCodeInMacroFusion(CC);
     29      1.1  joerg }
     30      1.1  joerg 
     31      1.1  joerg /// Check if the instr pair, FirstMI and SecondMI, should be fused
     32      1.1  joerg /// together. Given SecondMI, when FirstMI is unspecified, then check if
     33      1.1  joerg /// SecondMI may be part of a fused pair at all.
     34      1.1  joerg static bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
     35      1.1  joerg                                    const TargetSubtargetInfo &TSI,
     36      1.1  joerg                                    const MachineInstr *FirstMI,
     37      1.1  joerg                                    const MachineInstr &SecondMI) {
     38      1.1  joerg   const X86Subtarget &ST = static_cast<const X86Subtarget &>(TSI);
     39      1.1  joerg 
     40      1.1  joerg   // Check if this processor supports any kind of fusion.
     41      1.1  joerg   if (!(ST.hasBranchFusion() || ST.hasMacroFusion()))
     42      1.1  joerg     return false;
     43      1.1  joerg 
     44  1.1.1.2  joerg   const X86::SecondMacroFusionInstKind BranchKind = classifySecond(SecondMI);
     45      1.1  joerg 
     46  1.1.1.2  joerg   if (BranchKind == X86::SecondMacroFusionInstKind::Invalid)
     47      1.1  joerg     return false; // Second cannot be fused with anything.
     48      1.1  joerg 
     49      1.1  joerg   if (FirstMI == nullptr)
     50      1.1  joerg     return true; // We're only checking whether Second can be fused at all.
     51      1.1  joerg 
     52  1.1.1.2  joerg   const X86::FirstMacroFusionInstKind TestKind = classifyFirst(*FirstMI);
     53      1.1  joerg 
     54      1.1  joerg   if (ST.hasBranchFusion()) {
     55      1.1  joerg     // Branch fusion can merge CMP and TEST with all conditional jumps.
     56  1.1.1.2  joerg     return (TestKind == X86::FirstMacroFusionInstKind::Cmp ||
     57  1.1.1.2  joerg             TestKind == X86::FirstMacroFusionInstKind::Test);
     58      1.1  joerg   }
     59      1.1  joerg 
     60      1.1  joerg   if (ST.hasMacroFusion()) {
     61  1.1.1.2  joerg     return X86::isMacroFused(TestKind, BranchKind);
     62      1.1  joerg   }
     63      1.1  joerg 
     64  1.1.1.2  joerg   llvm_unreachable("unknown fusion type");
     65      1.1  joerg }
     66      1.1  joerg 
     67      1.1  joerg namespace llvm {
     68      1.1  joerg 
     69      1.1  joerg std::unique_ptr<ScheduleDAGMutation>
     70      1.1  joerg createX86MacroFusionDAGMutation () {
     71      1.1  joerg   return createBranchMacroFusionDAGMutation(shouldScheduleAdjacent);
     72      1.1  joerg }
     73      1.1  joerg 
     74      1.1  joerg } // end namespace llvm
     75