Support.h revision 343210
1//===--------------------- Support.h ----------------------------*- 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/// Helper functions used by various pipeline components. 12/// 13//===----------------------------------------------------------------------===// 14 15#ifndef LLVM_MCA_SUPPORT_H 16#define LLVM_MCA_SUPPORT_H 17 18#include "llvm/ADT/ArrayRef.h" 19#include "llvm/ADT/SmallVector.h" 20#include "llvm/MC/MCSchedule.h" 21#include "llvm/Support/Error.h" 22 23namespace llvm { 24namespace mca { 25 26template <typename T> 27class InstructionError : public ErrorInfo<InstructionError<T>> { 28public: 29 static char ID; 30 std::string Message; 31 const T &Inst; 32 33 InstructionError(std::string M, const T &MCI) 34 : Message(std::move(M)), Inst(MCI) {} 35 36 void log(raw_ostream &OS) const override { OS << Message; } 37 38 std::error_code convertToErrorCode() const override { 39 return inconvertibleErrorCode(); 40 } 41}; 42 43template <typename T> char InstructionError<T>::ID; 44 45/// This class represents the number of cycles per resource (fractions of 46/// cycles). That quantity is managed here as a ratio, and accessed via the 47/// double cast-operator below. The two quantities, number of cycles and 48/// number of resources, are kept separate. This is used by the 49/// ResourcePressureView to calculate the average resource cycles 50/// per instruction/iteration. 51class ResourceCycles { 52 unsigned Numerator, Denominator; 53 54public: 55 ResourceCycles() : Numerator(0), Denominator(1) {} 56 ResourceCycles(unsigned Cycles, unsigned ResourceUnits = 1) 57 : Numerator(Cycles), Denominator(ResourceUnits) {} 58 59 operator double() const { 60 assert(Denominator && "Invalid denominator (must be non-zero)."); 61 return (Denominator == 1) ? Numerator : (double)Numerator / Denominator; 62 } 63 64 // Add the components of RHS to this instance. Instead of calculating 65 // the final value here, we keep track of the numerator and denominator 66 // separately, to reduce floating point error. 67 ResourceCycles &operator+=(const ResourceCycles &RHS) { 68 if (Denominator == RHS.Denominator) 69 Numerator += RHS.Numerator; 70 else { 71 // Create a common denominator for LHS and RHS by calculating the least 72 // common multiple from the GCD. 73 unsigned GCD = GreatestCommonDivisor64(Denominator, RHS.Denominator); 74 unsigned LCM = (Denominator * RHS.Denominator) / GCD; 75 unsigned LHSNumerator = Numerator * (LCM / Denominator); 76 unsigned RHSNumerator = RHS.Numerator * (LCM / RHS.Denominator); 77 Numerator = LHSNumerator + RHSNumerator; 78 Denominator = LCM; 79 } 80 return *this; 81 } 82}; 83 84/// Populates vector Masks with processor resource masks. 85/// 86/// The number of bits set in a mask depends on the processor resource type. 87/// Each processor resource mask has at least one bit set. For groups, the 88/// number of bits set in the mask is equal to the cardinality of the group plus 89/// one. Excluding the most significant bit, the remaining bits in the mask 90/// identify processor resources that are part of the group. 91/// 92/// Example: 93/// 94/// ResourceA -- Mask: 0b001 95/// ResourceB -- Mask: 0b010 96/// ResourceAB -- Mask: 0b100 U (ResourceA::Mask | ResourceB::Mask) == 0b111 97/// 98/// ResourceAB is a processor resource group containing ResourceA and ResourceB. 99/// Each resource mask uniquely identifies a resource; both ResourceA and 100/// ResourceB only have one bit set. 101/// ResourceAB is a group; excluding the most significant bit in the mask, the 102/// remaining bits identify the composition of the group. 103/// 104/// Resource masks are used by the ResourceManager to solve set membership 105/// problems with simple bit manipulation operations. 106void computeProcResourceMasks(const MCSchedModel &SM, 107 MutableArrayRef<uint64_t> Masks); 108 109/// Compute the reciprocal block throughput from a set of processor resource 110/// cycles. The reciprocal block throughput is computed as the MAX between: 111/// - NumMicroOps / DispatchWidth 112/// - ProcResourceCycles / #ProcResourceUnits (for every consumed resource). 113double computeBlockRThroughput(const MCSchedModel &SM, unsigned DispatchWidth, 114 unsigned NumMicroOps, 115 ArrayRef<unsigned> ProcResourceUsage); 116} // namespace mca 117} // namespace llvm 118 119#endif // LLVM_MCA_SUPPORT_H 120