1 // Copyright 2015 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/compiler/instruction-scheduler.h" 6 7 namespace v8 { 8 namespace internal { 9 namespace compiler { 10 SchedulerSupported()11bool InstructionScheduler::SchedulerSupported() { return true; } 12 13 GetTargetInstructionFlags(const Instruction * instr) const14int InstructionScheduler::GetTargetInstructionFlags( 15 const Instruction* instr) const { 16 switch (instr->arch_opcode()) { 17 case kX64Add: 18 case kX64Add32: 19 case kX64And: 20 case kX64And32: 21 case kX64Cmp: 22 case kX64Cmp32: 23 case kX64Cmp16: 24 case kX64Cmp8: 25 case kX64Test: 26 case kX64Test32: 27 case kX64Test16: 28 case kX64Test8: 29 case kX64Or: 30 case kX64Or32: 31 case kX64Xor: 32 case kX64Xor32: 33 case kX64Sub: 34 case kX64Sub32: 35 case kX64Imul: 36 case kX64Imul32: 37 case kX64ImulHigh32: 38 case kX64UmulHigh32: 39 case kX64Not: 40 case kX64Not32: 41 case kX64Neg: 42 case kX64Neg32: 43 case kX64Shl: 44 case kX64Shl32: 45 case kX64Shr: 46 case kX64Shr32: 47 case kX64Sar: 48 case kX64Sar32: 49 case kX64Ror: 50 case kX64Ror32: 51 case kX64Lzcnt: 52 case kX64Lzcnt32: 53 case kX64Tzcnt: 54 case kX64Tzcnt32: 55 case kX64Popcnt: 56 case kX64Popcnt32: 57 case kX64Bswap: 58 case kX64Bswap32: 59 case kSSEFloat32Cmp: 60 case kSSEFloat32Add: 61 case kSSEFloat32Sub: 62 case kSSEFloat32Mul: 63 case kSSEFloat32Div: 64 case kSSEFloat32Abs: 65 case kSSEFloat32Neg: 66 case kSSEFloat32Sqrt: 67 case kSSEFloat32Round: 68 case kSSEFloat32ToFloat64: 69 case kSSEFloat64Cmp: 70 case kSSEFloat64Add: 71 case kSSEFloat64Sub: 72 case kSSEFloat64Mul: 73 case kSSEFloat64Div: 74 case kSSEFloat64Mod: 75 case kSSEFloat64Abs: 76 case kSSEFloat64Neg: 77 case kSSEFloat64Sqrt: 78 case kSSEFloat64Round: 79 case kSSEFloat32Max: 80 case kSSEFloat64Max: 81 case kSSEFloat32Min: 82 case kSSEFloat64Min: 83 case kSSEFloat64ToFloat32: 84 case kSSEFloat32ToInt32: 85 case kSSEFloat32ToUint32: 86 case kSSEFloat64ToInt32: 87 case kSSEFloat64ToUint32: 88 case kSSEFloat64ToInt64: 89 case kSSEFloat32ToInt64: 90 case kSSEFloat64ToUint64: 91 case kSSEFloat32ToUint64: 92 case kSSEInt32ToFloat64: 93 case kSSEInt32ToFloat32: 94 case kSSEInt64ToFloat32: 95 case kSSEInt64ToFloat64: 96 case kSSEUint64ToFloat32: 97 case kSSEUint64ToFloat64: 98 case kSSEUint32ToFloat64: 99 case kSSEUint32ToFloat32: 100 case kSSEFloat64ExtractLowWord32: 101 case kSSEFloat64ExtractHighWord32: 102 case kSSEFloat64InsertLowWord32: 103 case kSSEFloat64InsertHighWord32: 104 case kSSEFloat64LoadLowWord32: 105 case kSSEFloat64SilenceNaN: 106 case kAVXFloat32Cmp: 107 case kAVXFloat32Add: 108 case kAVXFloat32Sub: 109 case kAVXFloat32Mul: 110 case kAVXFloat32Div: 111 case kAVXFloat64Cmp: 112 case kAVXFloat64Add: 113 case kAVXFloat64Sub: 114 case kAVXFloat64Mul: 115 case kAVXFloat64Div: 116 case kAVXFloat64Abs: 117 case kAVXFloat64Neg: 118 case kAVXFloat32Abs: 119 case kAVXFloat32Neg: 120 case kX64BitcastFI: 121 case kX64BitcastDL: 122 case kX64BitcastIF: 123 case kX64BitcastLD: 124 case kX64Lea32: 125 case kX64Lea: 126 case kX64Dec32: 127 case kX64Inc32: 128 case kX64F32x4Splat: 129 case kX64F32x4ExtractLane: 130 case kX64F32x4ReplaceLane: 131 case kX64F32x4RecipApprox: 132 case kX64F32x4RecipSqrtApprox: 133 case kX64F32x4Abs: 134 case kX64F32x4Neg: 135 case kX64F32x4Add: 136 case kX64F32x4AddHoriz: 137 case kX64F32x4Sub: 138 case kX64F32x4Mul: 139 case kX64F32x4Min: 140 case kX64F32x4Max: 141 case kX64F32x4Eq: 142 case kX64F32x4Ne: 143 case kX64F32x4Lt: 144 case kX64F32x4Le: 145 case kX64I32x4Splat: 146 case kX64I32x4ExtractLane: 147 case kX64I32x4ReplaceLane: 148 case kX64I32x4Neg: 149 case kX64I32x4Shl: 150 case kX64I32x4ShrS: 151 case kX64I32x4Add: 152 case kX64I32x4AddHoriz: 153 case kX64I32x4Sub: 154 case kX64I32x4Mul: 155 case kX64I32x4MinS: 156 case kX64I32x4MaxS: 157 case kX64I32x4Eq: 158 case kX64I32x4Ne: 159 case kX64I32x4GtS: 160 case kX64I32x4GeS: 161 case kX64I32x4ShrU: 162 case kX64I32x4MinU: 163 case kX64I32x4MaxU: 164 case kX64I32x4GtU: 165 case kX64I32x4GeU: 166 case kX64I16x8Splat: 167 case kX64I16x8ExtractLane: 168 case kX64I16x8ReplaceLane: 169 case kX64I16x8Neg: 170 case kX64I16x8Shl: 171 case kX64I16x8ShrS: 172 case kX64I16x8Add: 173 case kX64I16x8AddSaturateS: 174 case kX64I16x8AddHoriz: 175 case kX64I16x8Sub: 176 case kX64I16x8SubSaturateS: 177 case kX64I16x8Mul: 178 case kX64I16x8MinS: 179 case kX64I16x8MaxS: 180 case kX64I16x8Eq: 181 case kX64I16x8Ne: 182 case kX64I16x8GtS: 183 case kX64I16x8GeS: 184 case kX64I16x8ShrU: 185 case kX64I16x8AddSaturateU: 186 case kX64I16x8SubSaturateU: 187 case kX64I16x8MinU: 188 case kX64I16x8MaxU: 189 case kX64I16x8GtU: 190 case kX64I16x8GeU: 191 case kX64I8x16Splat: 192 case kX64I8x16ExtractLane: 193 case kX64I8x16ReplaceLane: 194 case kX64I8x16Neg: 195 case kX64I8x16Add: 196 case kX64I8x16AddSaturateS: 197 case kX64I8x16Sub: 198 case kX64I8x16SubSaturateS: 199 case kX64I8x16MinS: 200 case kX64I8x16MaxS: 201 case kX64I8x16Eq: 202 case kX64I8x16Ne: 203 case kX64I8x16GtS: 204 case kX64I8x16GeS: 205 case kX64I8x16AddSaturateU: 206 case kX64I8x16SubSaturateU: 207 case kX64I8x16MinU: 208 case kX64I8x16MaxU: 209 case kX64I8x16GtU: 210 case kX64I8x16GeU: 211 case kX64S128And: 212 case kX64S128Or: 213 case kX64S128Xor: 214 case kX64S128Not: 215 case kX64S128Select: 216 case kX64S128Zero: 217 return (instr->addressing_mode() == kMode_None) 218 ? kNoOpcodeFlags 219 : kIsLoadOperation | kHasSideEffect; 220 221 case kX64Idiv: 222 case kX64Idiv32: 223 case kX64Udiv: 224 case kX64Udiv32: 225 return (instr->addressing_mode() == kMode_None) 226 ? kMayNeedDeoptOrTrapCheck 227 : kMayNeedDeoptOrTrapCheck | kIsLoadOperation | kHasSideEffect; 228 229 case kX64Movsxbl: 230 case kX64Movzxbl: 231 case kX64Movsxbq: 232 case kX64Movzxbq: 233 case kX64Movsxwl: 234 case kX64Movzxwl: 235 case kX64Movsxwq: 236 case kX64Movzxwq: 237 case kX64Movsxlq: 238 DCHECK_LE(1, instr->InputCount()); 239 return instr->InputAt(0)->IsRegister() ? kNoOpcodeFlags 240 : kIsLoadOperation; 241 242 case kX64Movb: 243 case kX64Movw: 244 return kHasSideEffect; 245 246 case kX64Movl: 247 if (instr->HasOutput()) { 248 DCHECK_LE(1, instr->InputCount()); 249 return instr->InputAt(0)->IsRegister() ? kNoOpcodeFlags 250 : kIsLoadOperation; 251 } else { 252 return kHasSideEffect; 253 } 254 255 case kX64Movq: 256 case kX64Movsd: 257 case kX64Movss: 258 case kX64Movdqu: 259 return instr->HasOutput() ? kIsLoadOperation : kHasSideEffect; 260 261 case kX64StackCheck: 262 case kX64Peek: 263 return kIsLoadOperation; 264 265 case kX64Push: 266 case kX64Poke: 267 return kHasSideEffect; 268 269 case kLFence: 270 return kHasSideEffect; 271 272 case kX64Word64AtomicLoadUint8: 273 case kX64Word64AtomicLoadUint16: 274 case kX64Word64AtomicLoadUint32: 275 case kX64Word64AtomicLoadUint64: 276 return kIsLoadOperation; 277 278 case kX64Word64AtomicStoreWord8: 279 case kX64Word64AtomicStoreWord16: 280 case kX64Word64AtomicStoreWord32: 281 case kX64Word64AtomicStoreWord64: 282 case kX64Word64AtomicAddUint8: 283 case kX64Word64AtomicAddUint16: 284 case kX64Word64AtomicAddUint32: 285 case kX64Word64AtomicAddUint64: 286 case kX64Word64AtomicSubUint8: 287 case kX64Word64AtomicSubUint16: 288 case kX64Word64AtomicSubUint32: 289 case kX64Word64AtomicSubUint64: 290 case kX64Word64AtomicAndUint8: 291 case kX64Word64AtomicAndUint16: 292 case kX64Word64AtomicAndUint32: 293 case kX64Word64AtomicAndUint64: 294 case kX64Word64AtomicOrUint8: 295 case kX64Word64AtomicOrUint16: 296 case kX64Word64AtomicOrUint32: 297 case kX64Word64AtomicOrUint64: 298 case kX64Word64AtomicXorUint8: 299 case kX64Word64AtomicXorUint16: 300 case kX64Word64AtomicXorUint32: 301 case kX64Word64AtomicXorUint64: 302 case kX64Word64AtomicExchangeUint8: 303 case kX64Word64AtomicExchangeUint16: 304 case kX64Word64AtomicExchangeUint32: 305 case kX64Word64AtomicExchangeUint64: 306 case kX64Word64AtomicCompareExchangeUint8: 307 case kX64Word64AtomicCompareExchangeUint16: 308 case kX64Word64AtomicCompareExchangeUint32: 309 case kX64Word64AtomicCompareExchangeUint64: 310 return kHasSideEffect; 311 312 #define CASE(Name) case k##Name: 313 COMMON_ARCH_OPCODE_LIST(CASE) 314 #undef CASE 315 // Already covered in architecture independent code. 316 UNREACHABLE(); 317 } 318 319 UNREACHABLE(); 320 } 321 322 GetInstructionLatency(const Instruction * instr)323int InstructionScheduler::GetInstructionLatency(const Instruction* instr) { 324 // Basic latency modeling for x64 instructions. They have been determined 325 // in an empirical way. 326 switch (instr->arch_opcode()) { 327 case kSSEFloat64Mul: 328 return 5; 329 case kX64Imul: 330 case kX64Imul32: 331 case kX64ImulHigh32: 332 case kX64UmulHigh32: 333 case kSSEFloat32Cmp: 334 case kSSEFloat32Add: 335 case kSSEFloat32Sub: 336 case kSSEFloat32Abs: 337 case kSSEFloat32Neg: 338 case kSSEFloat64Cmp: 339 case kSSEFloat64Add: 340 case kSSEFloat64Sub: 341 case kSSEFloat64Max: 342 case kSSEFloat64Min: 343 case kSSEFloat64Abs: 344 case kSSEFloat64Neg: 345 return 3; 346 case kSSEFloat32Mul: 347 case kSSEFloat32ToFloat64: 348 case kSSEFloat64ToFloat32: 349 case kSSEFloat32Round: 350 case kSSEFloat64Round: 351 case kSSEFloat32ToInt32: 352 case kSSEFloat32ToUint32: 353 case kSSEFloat64ToInt32: 354 case kSSEFloat64ToUint32: 355 return 4; 356 case kX64Idiv: 357 return 49; 358 case kX64Idiv32: 359 return 35; 360 case kX64Udiv: 361 return 38; 362 case kX64Udiv32: 363 return 26; 364 case kSSEFloat32Div: 365 case kSSEFloat64Div: 366 case kSSEFloat32Sqrt: 367 case kSSEFloat64Sqrt: 368 return 13; 369 case kSSEFloat32ToInt64: 370 case kSSEFloat64ToInt64: 371 case kSSEFloat32ToUint64: 372 case kSSEFloat64ToUint64: 373 return 10; 374 case kSSEFloat64Mod: 375 return 50; 376 case kArchTruncateDoubleToI: 377 return 6; 378 default: 379 return 1; 380 } 381 } 382 383 } // namespace compiler 384 } // namespace internal 385 } // namespace v8 386