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 23 namespace llvm { 24 namespace mca { 25 26 template <typename T> 27 class InstructionError : public ErrorInfo<InstructionError<T>> { 28 public: 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 43 template <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. 51 class ResourceCycles { 52 unsigned Numerator, Denominator; 53 54 public: 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. 106 void 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). 113 double 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