X86MacroFusion.cpp revision 321369
1//===- X86MacroFusion.cpp - X86 Macro Fusion ------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10/// \file This file contains the X86 implementation of the DAG scheduling 11/// mutation to pair instructions back to back. 12// 13//===----------------------------------------------------------------------===// 14 15#include "X86MacroFusion.h" 16#include "X86Subtarget.h" 17#include "llvm/Target/TargetInstrInfo.h" 18#include "llvm/CodeGen/MacroFusion.h" 19 20using namespace llvm; 21 22/// \brief Check if the instr pair, FirstMI and SecondMI, should be fused 23/// together. Given SecondMI, when FirstMI is unspecified, then check if 24/// SecondMI may be part of a fused pair at all. 25static bool shouldScheduleAdjacent(const TargetInstrInfo &TII, 26 const TargetSubtargetInfo &TSI, 27 const MachineInstr *FirstMI, 28 const MachineInstr &SecondMI) { 29 const X86Subtarget &ST = static_cast<const X86Subtarget&>(TSI); 30 // Check if this processor supports macro-fusion. Since this is a minor 31 // heuristic, we haven't specifically reserved a feature. hasAVX is a decent 32 // proxy for SandyBridge+. 33 if (!ST.hasAVX()) 34 return false; 35 36 enum { 37 FuseTest, 38 FuseCmp, 39 FuseInc 40 } FuseKind; 41 42 unsigned FirstOpcode = FirstMI 43 ? FirstMI->getOpcode() 44 : static_cast<unsigned>(X86::INSTRUCTION_LIST_END); 45 unsigned SecondOpcode = SecondMI.getOpcode(); 46 47 switch (SecondOpcode) { 48 default: 49 return false; 50 case X86::JE_1: 51 case X86::JNE_1: 52 case X86::JL_1: 53 case X86::JLE_1: 54 case X86::JG_1: 55 case X86::JGE_1: 56 FuseKind = FuseInc; 57 break; 58 case X86::JB_1: 59 case X86::JBE_1: 60 case X86::JA_1: 61 case X86::JAE_1: 62 FuseKind = FuseCmp; 63 break; 64 case X86::JS_1: 65 case X86::JNS_1: 66 case X86::JP_1: 67 case X86::JNP_1: 68 case X86::JO_1: 69 case X86::JNO_1: 70 FuseKind = FuseTest; 71 break; 72 } 73 74 switch (FirstOpcode) { 75 default: 76 return false; 77 case X86::TEST8rr: 78 case X86::TEST16rr: 79 case X86::TEST32rr: 80 case X86::TEST64rr: 81 case X86::TEST8ri: 82 case X86::TEST16ri: 83 case X86::TEST32ri: 84 case X86::TEST32i32: 85 case X86::TEST64i32: 86 case X86::TEST64ri32: 87 case X86::TEST8rm: 88 case X86::TEST16rm: 89 case X86::TEST32rm: 90 case X86::TEST64rm: 91 case X86::TEST8ri_NOREX: 92 case X86::AND16i16: 93 case X86::AND16ri: 94 case X86::AND16ri8: 95 case X86::AND16rm: 96 case X86::AND16rr: 97 case X86::AND32i32: 98 case X86::AND32ri: 99 case X86::AND32ri8: 100 case X86::AND32rm: 101 case X86::AND32rr: 102 case X86::AND64i32: 103 case X86::AND64ri32: 104 case X86::AND64ri8: 105 case X86::AND64rm: 106 case X86::AND64rr: 107 case X86::AND8i8: 108 case X86::AND8ri: 109 case X86::AND8rm: 110 case X86::AND8rr: 111 return true; 112 case X86::CMP16i16: 113 case X86::CMP16ri: 114 case X86::CMP16ri8: 115 case X86::CMP16rm: 116 case X86::CMP16rr: 117 case X86::CMP32i32: 118 case X86::CMP32ri: 119 case X86::CMP32ri8: 120 case X86::CMP32rm: 121 case X86::CMP32rr: 122 case X86::CMP64i32: 123 case X86::CMP64ri32: 124 case X86::CMP64ri8: 125 case X86::CMP64rm: 126 case X86::CMP64rr: 127 case X86::CMP8i8: 128 case X86::CMP8ri: 129 case X86::CMP8rm: 130 case X86::CMP8rr: 131 case X86::ADD16i16: 132 case X86::ADD16ri: 133 case X86::ADD16ri8: 134 case X86::ADD16ri8_DB: 135 case X86::ADD16ri_DB: 136 case X86::ADD16rm: 137 case X86::ADD16rr: 138 case X86::ADD16rr_DB: 139 case X86::ADD32i32: 140 case X86::ADD32ri: 141 case X86::ADD32ri8: 142 case X86::ADD32ri8_DB: 143 case X86::ADD32ri_DB: 144 case X86::ADD32rm: 145 case X86::ADD32rr: 146 case X86::ADD32rr_DB: 147 case X86::ADD64i32: 148 case X86::ADD64ri32: 149 case X86::ADD64ri32_DB: 150 case X86::ADD64ri8: 151 case X86::ADD64ri8_DB: 152 case X86::ADD64rm: 153 case X86::ADD64rr: 154 case X86::ADD64rr_DB: 155 case X86::ADD8i8: 156 case X86::ADD8mi: 157 case X86::ADD8mr: 158 case X86::ADD8ri: 159 case X86::ADD8rm: 160 case X86::ADD8rr: 161 case X86::SUB16i16: 162 case X86::SUB16ri: 163 case X86::SUB16ri8: 164 case X86::SUB16rm: 165 case X86::SUB16rr: 166 case X86::SUB32i32: 167 case X86::SUB32ri: 168 case X86::SUB32ri8: 169 case X86::SUB32rm: 170 case X86::SUB32rr: 171 case X86::SUB64i32: 172 case X86::SUB64ri32: 173 case X86::SUB64ri8: 174 case X86::SUB64rm: 175 case X86::SUB64rr: 176 case X86::SUB8i8: 177 case X86::SUB8ri: 178 case X86::SUB8rm: 179 case X86::SUB8rr: 180 return FuseKind == FuseCmp || FuseKind == FuseInc; 181 case X86::INC16r: 182 case X86::INC32r: 183 case X86::INC64r: 184 case X86::INC8r: 185 case X86::DEC16r: 186 case X86::DEC32r: 187 case X86::DEC64r: 188 case X86::DEC8r: 189 return FuseKind == FuseInc; 190 case X86::INSTRUCTION_LIST_END: 191 return true; 192 } 193} 194 195namespace llvm { 196 197std::unique_ptr<ScheduleDAGMutation> 198createX86MacroFusionDAGMutation () { 199 return createBranchMacroFusionDAGMutation(shouldScheduleAdjacent); 200} 201 202} // end namespace llvm 203