brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.0 KiB · f8b8a2d Raw
112 lines · cpp
1//===--------------------- Support.cpp --------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8/// \file9///10/// This file implements a few helper functions used by various pipeline11/// components.12///13//===----------------------------------------------------------------------===//14 15#include "llvm/MCA/Support.h"16#include "llvm/MC/MCSchedule.h"17#include <numeric>18 19namespace llvm {20namespace mca {21 22#define DEBUG_TYPE "llvm-mca"23 24ReleaseAtCycles &ReleaseAtCycles::operator+=(const ReleaseAtCycles &RHS) {25  if (Denominator == RHS.Denominator)26    Numerator += RHS.Numerator;27  else {28    // Create a common denominator for LHS and RHS by calculating the least29    // common multiple from the GCD.30    unsigned GCD = std::gcd(Denominator, RHS.Denominator);31    unsigned LCM = (Denominator * RHS.Denominator) / GCD;32    unsigned LHSNumerator = Numerator * (LCM / Denominator);33    unsigned RHSNumerator = RHS.Numerator * (LCM / RHS.Denominator);34    Numerator = LHSNumerator + RHSNumerator;35    Denominator = LCM;36  }37  return *this;38}39 40void computeProcResourceMasks(const MCSchedModel &SM,41                              MutableArrayRef<uint64_t> Masks) {42  unsigned ProcResourceID = 0;43 44  assert(Masks.size() == SM.getNumProcResourceKinds() &&45         "Invalid number of elements");46  // Resource at index 0 is the 'InvalidUnit'. Set an invalid mask for it.47  Masks[0] = 0;48 49  // Create a unique bitmask for every processor resource unit.50  for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) {51    const MCProcResourceDesc &Desc = *SM.getProcResource(I);52    if (Desc.SubUnitsIdxBegin)53      continue;54    Masks[I] = 1ULL << ProcResourceID;55    ProcResourceID++;56  }57 58  // Create a unique bitmask for every processor resource group.59  for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) {60    const MCProcResourceDesc &Desc = *SM.getProcResource(I);61    if (!Desc.SubUnitsIdxBegin)62      continue;63    Masks[I] = 1ULL << ProcResourceID;64    for (unsigned U = 0; U < Desc.NumUnits; ++U) {65      uint64_t OtherMask = Masks[Desc.SubUnitsIdxBegin[U]];66      Masks[I] |= OtherMask;67    }68    ProcResourceID++;69  }70 71#ifndef NDEBUG72  LLVM_DEBUG(dbgs() << "\nProcessor resource masks:"73                    << "\n");74  for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) {75    const MCProcResourceDesc &Desc = *SM.getProcResource(I);76    LLVM_DEBUG(dbgs() << '[' << format_decimal(I,2) << "] " << " - "77                      << format_hex(Masks[I],16) << " - "78                      << Desc.Name << '\n');79  }80#endif81}82 83double computeBlockRThroughput(const MCSchedModel &SM, unsigned DispatchWidth,84                               unsigned NumMicroOps,85                               ArrayRef<unsigned> ProcResourceUsage) {86  // The block throughput is bounded from above by the hardware dispatch87  // throughput. That is because the DispatchWidth is an upper bound on the88  // number of opcodes that can be part of a single dispatch group.89  double Max = static_cast<double>(NumMicroOps) / DispatchWidth;90 91  // The block throughput is also limited by the amount of hardware parallelism.92  // The number of available resource units affects the resource pressure93  // distribution, as well as how many blocks can be executed every cycle.94  for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) {95    unsigned ReleaseAtCycles = ProcResourceUsage[I];96    if (!ReleaseAtCycles)97      continue;98 99    const MCProcResourceDesc &MCDesc = *SM.getProcResource(I);100    double Throughput = static_cast<double>(ReleaseAtCycles) / MCDesc.NumUnits;101    Max = std::max(Max, Throughput);102  }103 104  // The block reciprocal throughput is computed as the MAX of:105  //  - (NumMicroOps / DispatchWidth)106  //  - (NumUnits / ReleaseAtCycles)   for every consumed processor resource.107  return Max;108}109 110} // namespace mca111} // namespace llvm112