blob: e11062f4d7227ca9741ace959f38d94c49beb6ec [file] [log] [blame]
Andrea Di Biagio35622482018-03-22 10:19:20 +00001//===--------------------- Support.cpp --------------------------*- C++ -*-===//
Andrea Di Biagio4704f032018-03-20 12:25:54 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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-exception
Andrea Di Biagio4704f032018-03-20 12:25:54 +00006//
7//===----------------------------------------------------------------------===//
8/// \file
9///
Matt Davisdea343d2018-06-25 16:53:00 +000010/// This file implements a few helper functions used by various pipeline
Andrea Di Biagio4704f032018-03-20 12:25:54 +000011/// components.
12///
13//===----------------------------------------------------------------------===//
14
Clement Courbetcc5e6a72018-12-17 08:08:31 +000015#include "llvm/MCA/Support.h"
Andrea Di Biagio4704f032018-03-20 12:25:54 +000016#include "llvm/MC/MCSchedule.h"
17
Fangrui Song5a8fd652018-10-30 15:56:08 +000018namespace llvm {
Andrea Di Biagio4704f032018-03-20 12:25:54 +000019namespace mca {
20
Andrea Di Biagio97ed0762019-01-10 13:59:13 +000021#define DEBUG_TYPE "llvm-mca"
22
Andrea Di Biagio4704f032018-03-20 12:25:54 +000023void computeProcResourceMasks(const MCSchedModel &SM,
Andrea Di Biagio97ed0762019-01-10 13:59:13 +000024 MutableArrayRef<uint64_t> Masks) {
Andrea Di Biagio4704f032018-03-20 12:25:54 +000025 unsigned ProcResourceID = 0;
26
Andrea Di Biagio97ed0762019-01-10 13:59:13 +000027 assert(Masks.size() == SM.getNumProcResourceKinds() &&
28 "Invalid number of elements");
29 // Resource at index 0 is the 'InvalidUnit'. Set an invalid mask for it.
30 Masks[0] = 0;
31
Andrea Di Biagio4704f032018-03-20 12:25:54 +000032 // Create a unique bitmask for every processor resource unit.
Andrea Di Biagio4704f032018-03-20 12:25:54 +000033 for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) {
34 const MCProcResourceDesc &Desc = *SM.getProcResource(I);
35 if (Desc.SubUnitsIdxBegin)
36 continue;
37 Masks[I] = 1ULL << ProcResourceID;
38 ProcResourceID++;
39 }
40
41 // Create a unique bitmask for every processor resource group.
42 for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) {
43 const MCProcResourceDesc &Desc = *SM.getProcResource(I);
44 if (!Desc.SubUnitsIdxBegin)
45 continue;
46 Masks[I] = 1ULL << ProcResourceID;
47 for (unsigned U = 0; U < Desc.NumUnits; ++U) {
48 uint64_t OtherMask = Masks[Desc.SubUnitsIdxBegin[U]];
49 Masks[I] |= OtherMask;
50 }
51 ProcResourceID++;
52 }
Andrea Di Biagio97ed0762019-01-10 13:59:13 +000053
54#ifndef NDEBUG
55 LLVM_DEBUG(dbgs() << "\nProcessor resource masks:"
56 << "\n");
57 for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) {
58 const MCProcResourceDesc &Desc = *SM.getProcResource(I);
59 LLVM_DEBUG(dbgs() << '[' << I << "] " << Desc.Name << " - " << Masks[I]
60 << '\n');
61 }
62#endif
Andrea Di Biagio4704f032018-03-20 12:25:54 +000063}
Andrea Di Biagiobdc67062018-06-01 14:35:21 +000064
65double computeBlockRThroughput(const MCSchedModel &SM, unsigned DispatchWidth,
66 unsigned NumMicroOps,
67 ArrayRef<unsigned> ProcResourceUsage) {
68 // The block throughput is bounded from above by the hardware dispatch
69 // throughput. That is because the DispatchWidth is an upper bound on the
70 // number of opcodes that can be part of a single dispatch group.
71 double Max = static_cast<double>(NumMicroOps) / DispatchWidth;
72
73 // The block throughput is also limited by the amount of hardware parallelism.
74 // The number of available resource units affects the resource pressure
75 // distribution, as well as how many blocks can be executed every cycle.
76 for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) {
77 unsigned ResourceCycles = ProcResourceUsage[I];
78 if (!ResourceCycles)
79 continue;
80
81 const MCProcResourceDesc &MCDesc = *SM.getProcResource(I);
82 double Throughput = static_cast<double>(ResourceCycles) / MCDesc.NumUnits;
83 Max = std::max(Max, Throughput);
84 }
85
86 // The block reciprocal throughput is computed as the MAX of:
87 // - (NumMicroOps / DispatchWidth)
88 // - (NumUnits / ResourceCycles) for every consumed processor resource.
89 return Max;
90}
91
Andrea Di Biagio4704f032018-03-20 12:25:54 +000092} // namespace mca
Fangrui Song5a8fd652018-10-30 15:56:08 +000093} // namespace llvm