OLD | NEW |
(Empty) | |
| 1 //===-- NaClBitcodeValueDist.cpp ------------------------------------------===// |
| 2 // Implements (nested) distribution maps to separate out values at each |
| 3 // index in a bitcode record. |
| 4 // |
| 5 // The LLVM Compiler Infrastructure |
| 6 // |
| 7 // This file is distributed under the University of Illinois Open Source |
| 8 // License. See LICENSE.TXT for details. |
| 9 // |
| 10 //===----------------------------------------------------------------------===// |
| 11 |
| 12 #include "llvm/ADT/STLExtras.h" |
| 13 #include "llvm/Bitcode/NaCl/NaClBitcodeValueDist.h" |
| 14 #include "llvm/Support/DataTypes.h" |
| 15 |
| 16 using namespace llvm; |
| 17 |
| 18 /// Constant defining cutoff for value distributions. All values less than |
| 19 /// this constant will be stored as a singleton range. |
| 20 static NaClBitcodeDistValue ValueDistSingletonCutoff = |
| 21 (NaClBitcodeDistValue)1 << 6; |
| 22 |
| 23 /// Largest value possible. |
| 24 static NaClBitcodeDistValue MaxValue = ~((NaClBitcodeDistValue) 0); |
| 25 |
| 26 /// Cutoffs for value ranges, starting the first range at |
| 27 /// ValueDistSingetonCutoff, and ending the last range with MaxValue. |
| 28 static NaClBitcodeDistValue ValueCutoffs[] = { |
| 29 (NaClBitcodeDistValue)1 << 8, |
| 30 (NaClBitcodeDistValue)1 << 12, |
| 31 (NaClBitcodeDistValue)1 << 16, |
| 32 (NaClBitcodeDistValue)1 << 24, |
| 33 (NaClBitcodeDistValue)1 << 32 |
| 34 }; |
| 35 |
| 36 // Converts the value to the corresponding range (value) that will |
| 37 // be stored in a value distribution map. |
| 38 NaClValueRangeIndexType |
| 39 llvm::GetNaClValueRangeIndex(NaClBitcodeDistValue Value) { |
| 40 if (Value < ValueDistSingletonCutoff) |
| 41 return Value; |
| 42 |
| 43 size_t ValueCutoffsSize = array_lengthof(ValueCutoffs); |
| 44 for (size_t i = 0; i < ValueCutoffsSize; ++i) { |
| 45 if (Value < ValueCutoffs[i]) { |
| 46 return ValueDistSingletonCutoff + i; |
| 47 } |
| 48 } |
| 49 |
| 50 return ValueDistSingletonCutoff + ValueCutoffsSize; |
| 51 } |
| 52 |
| 53 NaClValueRangeType llvm::GetNaClValueRange(NaClValueRangeIndexType RangeIndex) { |
| 54 if (RangeIndex < ValueDistSingletonCutoff) |
| 55 return NaClValueRangeType(RangeIndex, RangeIndex); |
| 56 |
| 57 size_t Index = RangeIndex - ValueDistSingletonCutoff; |
| 58 size_t ValueCutoffsSize = array_lengthof(ValueCutoffs); |
| 59 if (Index >= ValueCutoffsSize) |
| 60 return NaClValueRangeType(ValueCutoffs[ValueCutoffsSize-1], MaxValue); |
| 61 else if (Index == 0) |
| 62 return NaClValueRangeType(ValueDistSingletonCutoff, ValueCutoffs[0]); |
| 63 else |
| 64 return NaClValueRangeType(ValueCutoffs[Index-1], ValueCutoffs[Index]-1); |
| 65 } |
| 66 |
| 67 NaClBitcodeValueDistElement NaClBitcodeValueDistElement::Sentinel; |
| 68 |
| 69 NaClBitcodeValueDistElement::~NaClBitcodeValueDistElement() {} |
| 70 |
| 71 NaClBitcodeDistElement *NaClBitcodeValueDistElement::CreateElement( |
| 72 NaClBitcodeDistValue Value) const { |
| 73 return new NaClBitcodeValueDistElement(); |
| 74 } |
| 75 |
| 76 double NaClBitcodeValueDistElement:: |
| 77 GetImportance(NaClBitcodeDistValue Value) const { |
| 78 NaClValueRangeType Pair = GetNaClValueRange(Value); |
| 79 return GetNumInstances() / static_cast<double>((Pair.second-Pair.first) + 1); |
| 80 } |
| 81 |
| 82 const char *NaClBitcodeValueDistElement::GetTitle() const { |
| 83 return "Values"; |
| 84 } |
| 85 |
| 86 const char *NaClBitcodeValueDistElement::GetValueHeader() const { |
| 87 return "Value / Range"; |
| 88 } |
| 89 |
| 90 void NaClBitcodeValueDistElement:: |
| 91 PrintRowValue(raw_ostream &Stream, |
| 92 NaClBitcodeDistValue Value, |
| 93 const NaClBitcodeDist *Distribution) const { |
| 94 NaClValueRangeType Range = GetNaClValueRange(Value); |
| 95 Stream << format("%" PRIu64, Range.first); |
| 96 if (Range.first != Range.second) { |
| 97 Stream << " .. " << format("%" PRIu64, Range.second); |
| 98 } |
| 99 } |
| 100 |
| 101 /// Defines the sentinel distribution element of range indices for untracked |
| 102 /// indices in the bitcode records, which need a clarifying print title. |
| 103 class NaClBitcodeUntrackedValueDistElement |
| 104 : public NaClBitcodeValueDistElement { |
| 105 public: |
| 106 static NaClBitcodeUntrackedValueDistElement Sentinel; |
| 107 |
| 108 virtual ~NaClBitcodeUntrackedValueDistElement(); |
| 109 |
| 110 virtual const char *GetTitle() const; |
| 111 |
| 112 private: |
| 113 NaClBitcodeUntrackedValueDistElement() |
| 114 : NaClBitcodeValueDistElement() |
| 115 {} |
| 116 }; |
| 117 |
| 118 NaClBitcodeUntrackedValueDistElement |
| 119 NaClBitcodeUntrackedValueDistElement::Sentinel; |
| 120 |
| 121 NaClBitcodeUntrackedValueDistElement::~NaClBitcodeUntrackedValueDistElement() {} |
| 122 |
| 123 const char *NaClBitcodeUntrackedValueDistElement::GetTitle() const { |
| 124 return "Values for untracked indices"; |
| 125 } |
| 126 |
| 127 NaClBitcodeValueDist:: |
| 128 NaClBitcodeValueDist(unsigned Index, bool AllRemainingIndices) |
| 129 : NaClBitcodeDist(RecordStorage, |
| 130 (AllRemainingIndices |
| 131 ? &NaClBitcodeUntrackedValueDistElement::Sentinel |
| 132 : &NaClBitcodeValueDistElement::Sentinel), |
| 133 RD_ValueDist), |
| 134 Index(Index), |
| 135 AllRemainingIndices(AllRemainingIndices) { |
| 136 } |
| 137 |
| 138 NaClBitcodeValueDist::~NaClBitcodeValueDist() {} |
| 139 |
| 140 void NaClBitcodeValueDist::GetValueList(const NaClBitcodeRecord &Record, |
| 141 ValueListType &ValueList) const { |
| 142 const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); |
| 143 if (AllRemainingIndices) { |
| 144 for (size_t i = Index, i_limit = Values.size(); i < i_limit; ++i) { |
| 145 ValueList.push_back(GetNaClValueRangeIndex(Values[i])); |
| 146 } |
| 147 } else { |
| 148 ValueList.push_back(GetNaClValueRangeIndex(Values[Index])); |
| 149 } |
| 150 } |
| 151 |
| 152 NaClBitcodeValueIndexDistElement NaClBitcodeValueIndexDistElement::Sentinel; |
| 153 |
| 154 NaClBitcodeValueIndexDistElement::~NaClBitcodeValueIndexDistElement() {} |
| 155 |
| 156 NaClBitcodeDistElement *NaClBitcodeValueIndexDistElement::CreateElement( |
| 157 NaClBitcodeDistValue Value) const { |
| 158 return new NaClBitcodeValueIndexDistElement(Value); |
| 159 } |
| 160 |
| 161 void NaClBitcodeValueIndexDistElement:: |
| 162 GetValueList(const NaClBitcodeRecord &Record, ValueListType &ValueList) const { |
| 163 unsigned i_limit = Record.GetValues().size(); |
| 164 if (i_limit > NaClValueIndexCutoff) i_limit = NaClValueIndexCutoff; |
| 165 for (size_t i = 0; i < i_limit; ++i) { |
| 166 ValueList.push_back(i); |
| 167 } |
| 168 } |
| 169 |
| 170 double NaClBitcodeValueIndexDistElement:: |
| 171 GetImportance(NaClBitcodeDistValue Value) const { |
| 172 // Since all indices (usually) have the same number of instances, |
| 173 // that is a bad measure of importance. Rather, we will base |
| 174 // importance in terms of the value distribution for the value |
| 175 // index. We would like the indicies with a few, large instance |
| 176 // counts, to appear before value indices with a uniform value |
| 177 // distribution. To do this, we will use the sum of the squares of |
| 178 // the number of instances for each value (i.e. sort by standard |
| 179 // deviation). |
| 180 double Sum = 0.0; |
| 181 for (NaClBitcodeDist::const_iterator |
| 182 Iter = ValueDist.begin(), IterEnd = ValueDist.end(); |
| 183 Iter != IterEnd; ++Iter) { |
| 184 const NaClBitcodeValueDistElement *Elmt = |
| 185 cast<NaClBitcodeValueDistElement>(Iter->second); |
| 186 double Count = static_cast<double>(Elmt->GetImportance(Iter->first)); |
| 187 Sum += Count * Count; |
| 188 } |
| 189 return Sum; |
| 190 } |
| 191 |
| 192 void NaClBitcodeValueIndexDistElement:: |
| 193 AddRecord(const NaClBitcodeRecord &Record) { |
| 194 NaClBitcodeDistElement::AddRecord(Record); |
| 195 ValueDist.AddRecord(Record); |
| 196 } |
| 197 |
| 198 const char *NaClBitcodeValueIndexDistElement::GetTitle() const { |
| 199 return "Value indices"; |
| 200 } |
| 201 |
| 202 const char *NaClBitcodeValueIndexDistElement::GetValueHeader() const { |
| 203 return " Index"; |
| 204 } |
| 205 |
| 206 void NaClBitcodeValueIndexDistElement:: |
| 207 PrintRowValue(raw_ostream &Stream, |
| 208 NaClBitcodeDistValue Value, |
| 209 const NaClBitcodeDist *Distribution) const { |
| 210 Stream << format("%7u", Value); |
| 211 } |
| 212 |
| 213 const SmallVectorImpl<NaClBitcodeDist*> *NaClBitcodeValueIndexDistElement:: |
| 214 GetNestedDistributions() const { |
| 215 return &NestedDists; |
| 216 } |
OLD | NEW |