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/CodeGen/MacroFusion.h" 18 #include "llvm/CodeGen/TargetInstrInfo.h" 19 20 using namespace llvm; 21 22 /// 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. 25 static 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. 31 if (!ST.hasMacroFusion()) 32 return false; 33 34 enum { 35 FuseTest, 36 FuseCmp, 37 FuseInc 38 } FuseKind; 39 40 unsigned FirstOpcode = FirstMI 41 ? FirstMI->getOpcode() 42 : static_cast<unsigned>(X86::INSTRUCTION_LIST_END); 43 unsigned SecondOpcode = SecondMI.getOpcode(); 44 45 switch (SecondOpcode) { 46 default: 47 return false; 48 case X86::JE_1: 49 case X86::JNE_1: 50 case X86::JL_1: 51 case X86::JLE_1: 52 case X86::JG_1: 53 case X86::JGE_1: 54 FuseKind = FuseInc; 55 break; 56 case X86::JB_1: 57 case X86::JBE_1: 58 case X86::JA_1: 59 case X86::JAE_1: 60 FuseKind = FuseCmp; 61 break; 62 case X86::JS_1: 63 case X86::JNS_1: 64 case X86::JP_1: 65 case X86::JNP_1: 66 case X86::JO_1: 67 case X86::JNO_1: 68 FuseKind = FuseTest; 69 break; 70 } 71 72 switch (FirstOpcode) { 73 default: 74 return false; 75 case X86::TEST8rr: 76 case X86::TEST16rr: 77 case X86::TEST32rr: 78 case X86::TEST64rr: 79 case X86::TEST8ri: 80 case X86::TEST16ri: 81 case X86::TEST32ri: 82 case X86::TEST32i32: 83 case X86::TEST64i32: 84 case X86::TEST64ri32: 85 case X86::TEST8mr: 86 case X86::TEST16mr: 87 case X86::TEST32mr: 88 case X86::TEST64mr: 89 case X86::AND16i16: 90 case X86::AND16ri: 91 case X86::AND16ri8: 92 case X86::AND16rm: 93 case X86::AND16rr: 94 case X86::AND32i32: 95 case X86::AND32ri: 96 case X86::AND32ri8: 97 case X86::AND32rm: 98 case X86::AND32rr: 99 case X86::AND64i32: 100 case X86::AND64ri32: 101 case X86::AND64ri8: 102 case X86::AND64rm: 103 case X86::AND64rr: 104 case X86::AND8i8: 105 case X86::AND8ri: 106 case X86::AND8rm: 107 case X86::AND8rr: 108 return true; 109 case X86::CMP16i16: 110 case X86::CMP16ri: 111 case X86::CMP16ri8: 112 case X86::CMP16rm: 113 case X86::CMP16rr: 114 case X86::CMP32i32: 115 case X86::CMP32ri: 116 case X86::CMP32ri8: 117 case X86::CMP32rm: 118 case X86::CMP32rr: 119 case X86::CMP64i32: 120 case X86::CMP64ri32: 121 case X86::CMP64ri8: 122 case X86::CMP64rm: 123 case X86::CMP64rr: 124 case X86::CMP8i8: 125 case X86::CMP8ri: 126 case X86::CMP8rm: 127 case X86::CMP8rr: 128 case X86::ADD16i16: 129 case X86::ADD16ri: 130 case X86::ADD16ri8: 131 case X86::ADD16ri8_DB: 132 case X86::ADD16ri_DB: 133 case X86::ADD16rm: 134 case X86::ADD16rr: 135 case X86::ADD16rr_DB: 136 case X86::ADD32i32: 137 case X86::ADD32ri: 138 case X86::ADD32ri8: 139 case X86::ADD32ri8_DB: 140 case X86::ADD32ri_DB: 141 case X86::ADD32rm: 142 case X86::ADD32rr: 143 case X86::ADD32rr_DB: 144 case X86::ADD64i32: 145 case X86::ADD64ri32: 146 case X86::ADD64ri32_DB: 147 case X86::ADD64ri8: 148 case X86::ADD64ri8_DB: 149 case X86::ADD64rm: 150 case X86::ADD64rr: 151 case X86::ADD64rr_DB: 152 case X86::ADD8i8: 153 case X86::ADD8ri: 154 case X86::ADD8rm: 155 case X86::ADD8rr: 156 case X86::SUB16i16: 157 case X86::SUB16ri: 158 case X86::SUB16ri8: 159 case X86::SUB16rm: 160 case X86::SUB16rr: 161 case X86::SUB32i32: 162 case X86::SUB32ri: 163 case X86::SUB32ri8: 164 case X86::SUB32rm: 165 case X86::SUB32rr: 166 case X86::SUB64i32: 167 case X86::SUB64ri32: 168 case X86::SUB64ri8: 169 case X86::SUB64rm: 170 case X86::SUB64rr: 171 case X86::SUB8i8: 172 case X86::SUB8ri: 173 case X86::SUB8rm: 174 case X86::SUB8rr: 175 return FuseKind == FuseCmp || FuseKind == FuseInc; 176 case X86::INC16r: 177 case X86::INC32r: 178 case X86::INC64r: 179 case X86::INC8r: 180 case X86::DEC16r: 181 case X86::DEC32r: 182 case X86::DEC64r: 183 case X86::DEC8r: 184 return FuseKind == FuseInc; 185 case X86::INSTRUCTION_LIST_END: 186 return true; 187 } 188 } 189 190 namespace llvm { 191 192 std::unique_ptr<ScheduleDAGMutation> 193 createX86MacroFusionDAGMutation () { 194 return createBranchMacroFusionDAGMutation(shouldScheduleAdjacent); 195 } 196 197 } // end namespace llvm 198