1 //===--------------------- Support.cpp --------------------------*- C++ -*-===// 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 /// \file 10 /// 11 /// This file implements a few helper functions used by various pipeline 12 /// components. 13 /// 14 //===----------------------------------------------------------------------===// 15 16 #include "llvm/MCA/Support.h" 17 #include "llvm/MC/MCSchedule.h" 18 19 namespace llvm { 20 namespace mca { 21 22 void computeProcResourceMasks(const MCSchedModel &SM, 23 SmallVectorImpl<uint64_t> &Masks) { 24 unsigned ProcResourceID = 0; 25 26 // Create a unique bitmask for every processor resource unit. 27 // Skip resource at index 0, since it always references 'InvalidUnit'. 28 Masks.resize(SM.getNumProcResourceKinds()); 29 for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) { 30 const MCProcResourceDesc &Desc = *SM.getProcResource(I); 31 if (Desc.SubUnitsIdxBegin) 32 continue; 33 Masks[I] = 1ULL << ProcResourceID; 34 ProcResourceID++; 35 } 36 37 // Create a unique bitmask for every processor resource group. 38 for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) { 39 const MCProcResourceDesc &Desc = *SM.getProcResource(I); 40 if (!Desc.SubUnitsIdxBegin) 41 continue; 42 Masks[I] = 1ULL << ProcResourceID; 43 for (unsigned U = 0; U < Desc.NumUnits; ++U) { 44 uint64_t OtherMask = Masks[Desc.SubUnitsIdxBegin[U]]; 45 Masks[I] |= OtherMask; 46 } 47 ProcResourceID++; 48 } 49 } 50 51 double computeBlockRThroughput(const MCSchedModel &SM, unsigned DispatchWidth, 52 unsigned NumMicroOps, 53 ArrayRef<unsigned> ProcResourceUsage) { 54 // The block throughput is bounded from above by the hardware dispatch 55 // throughput. That is because the DispatchWidth is an upper bound on the 56 // number of opcodes that can be part of a single dispatch group. 57 double Max = static_cast<double>(NumMicroOps) / DispatchWidth; 58 59 // The block throughput is also limited by the amount of hardware parallelism. 60 // The number of available resource units affects the resource pressure 61 // distribution, as well as how many blocks can be executed every cycle. 62 for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) { 63 unsigned ResourceCycles = ProcResourceUsage[I]; 64 if (!ResourceCycles) 65 continue; 66 67 const MCProcResourceDesc &MCDesc = *SM.getProcResource(I); 68 double Throughput = static_cast<double>(ResourceCycles) / MCDesc.NumUnits; 69 Max = std::max(Max, Throughput); 70 } 71 72 // The block reciprocal throughput is computed as the MAX of: 73 // - (NumMicroOps / DispatchWidth) 74 // - (NumUnits / ResourceCycles) for every consumed processor resource. 75 return Max; 76 } 77 78 } // namespace mca 79 } // namespace llvm 80