OLD | NEW |
(Empty) | |
| 1 //===- NaClBitcodeDist.cpp --------------------------------------*- C++ -*-===// |
| 2 // Internal implementation of PNaCl bitcode distributions. |
| 3 // |
| 4 // The LLVM Compiler Infrastructure |
| 5 // |
| 6 // This file is distributed under the University of Illinois Open Source |
| 7 // License. See LICENSE.TXT for details. |
| 8 // |
| 9 //===----------------------------------------------------------------------===// |
| 10 |
| 11 #include "llvm/Bitcode/NaCl/NaClBitcodeDist.h" |
| 12 |
| 13 using namespace llvm; |
| 14 |
| 15 NaClBitcodeDist::~NaClBitcodeDist() { |
| 16 RemoveCachedDistribution(); |
| 17 for (const_iterator Iter = begin(), IterEnd = end(); |
| 18 Iter != IterEnd; ++Iter) { |
| 19 delete Iter->second; |
| 20 } |
| 21 } |
| 22 |
| 23 NaClBitcodeDistElement *NaClBitcodeDist::CreateElement( |
| 24 NaClBitcodeDistValue Value) const { |
| 25 return Sentinel->CreateElement(Value); |
| 26 } |
| 27 |
| 28 void NaClBitcodeDist::GetValueList(const NaClBitcodeRecord &Record, |
| 29 ValueListType &ValueList) const { |
| 30 Sentinel->GetValueList(Record, ValueList); |
| 31 } |
| 32 |
| 33 void NaClBitcodeDist::AddRecord(const NaClBitcodeRecord &Record) { |
| 34 if (StorageKind != NaClBitcodeDist::RecordStorage) |
| 35 return; |
| 36 ValueListType ValueList; |
| 37 GetValueList(Record, ValueList); |
| 38 if (!ValueList.empty()) { |
| 39 RemoveCachedDistribution(); |
| 40 for (ValueListIterator |
| 41 Iter = ValueList.begin(), |
| 42 IterEnd = ValueList.end(); |
| 43 Iter != IterEnd; ++Iter) { |
| 44 NaClBitcodeDistElement *Element = GetElement(*Iter); |
| 45 Element->AddRecord(Record); |
| 46 ++Total; |
| 47 } |
| 48 } |
| 49 } |
| 50 |
| 51 void NaClBitcodeDist::AddBlock(const NaClBitcodeBlock &Block) { |
| 52 if (StorageKind != NaClBitcodeDist::BlockStorage) |
| 53 return; |
| 54 RemoveCachedDistribution(); |
| 55 ++Total; |
| 56 unsigned BlockID = Block.GetBlockID(); |
| 57 NaClBitcodeDistElement *Element = GetElement(BlockID); |
| 58 Element->AddBlock(Block); |
| 59 } |
| 60 |
| 61 void NaClBitcodeDist::Print(raw_ostream &Stream, |
| 62 const std::string &Indent) const { |
| 63 const Distribution *Dist = GetDistribution(); |
| 64 Stream << Indent; |
| 65 Sentinel->PrintTitle(Stream, this); |
| 66 Stream << Indent; |
| 67 Sentinel->PrintHeader(Stream); |
| 68 Stream << "\n"; |
| 69 bool NeedsHeader = false; |
| 70 for (size_t I = 0, E = Dist->size(); I < E; ++I) { |
| 71 if (NeedsHeader) { |
| 72 // Reprint the header so that rows are more readable. |
| 73 Stream << Indent << " " << Sentinel->GetTitle() << " (continued)\n"; |
| 74 Stream << Indent; |
| 75 Sentinel->PrintHeader(Stream); |
| 76 Stream << "\n"; |
| 77 } |
| 78 const DistPair &Pair = Dist->at(I); |
| 79 Stream << Indent; |
| 80 NaClBitcodeDistElement *Element = at(Pair.second); |
| 81 Element->PrintRow(Stream, Pair.second, this); |
| 82 NeedsHeader = Element->PrintNestedDistIfApplicable(Stream, Indent); |
| 83 } |
| 84 } |
| 85 |
| 86 void NaClBitcodeDist::Sort() const { |
| 87 RemoveCachedDistribution(); |
| 88 CachedDistribution = new Distribution(); |
| 89 for (const_iterator Iter = begin(), IterEnd = end(); |
| 90 Iter != IterEnd; ++Iter) { |
| 91 const NaClBitcodeDistElement *Elmt = Iter->second; |
| 92 // Only add if histogram element is non-empty. |
| 93 if (Elmt->GetNumInstances()) { |
| 94 double Importance = Elmt->GetImportance(Iter->first); |
| 95 CachedDistribution->push_back(std::make_pair(Importance, Iter->first)); |
| 96 } |
| 97 } |
| 98 // Sort in ascending order, based on importance. |
| 99 std::stable_sort(CachedDistribution->begin(), |
| 100 CachedDistribution->end()); |
| 101 // Reverse so most important appear first. |
| 102 std::reverse(CachedDistribution->begin(), |
| 103 CachedDistribution->end()); |
| 104 } |
| 105 |
| 106 NaClBitcodeDistElement::~NaClBitcodeDistElement() {} |
| 107 |
| 108 void NaClBitcodeDistElement::AddRecord(const NaClBitcodeRecord &Record) { |
| 109 ++NumInstances; |
| 110 } |
| 111 |
| 112 void NaClBitcodeDistElement::AddBlock(const NaClBitcodeBlock &Block) { |
| 113 ++NumInstances; |
| 114 } |
| 115 |
| 116 void NaClBitcodeDistElement::GetValueList(const NaClBitcodeRecord &Record, |
| 117 ValueListType &ValueList) const { |
| 118 // By default, assume no record values are defined. |
| 119 } |
| 120 |
| 121 double NaClBitcodeDistElement::GetImportance(NaClBitcodeDistValue Value) const { |
| 122 return static_cast<double>(NumInstances); |
| 123 } |
| 124 |
| 125 const char *NaClBitcodeDistElement::GetTitle() const { |
| 126 return "Distribution"; |
| 127 } |
| 128 |
| 129 void NaClBitcodeDistElement:: |
| 130 PrintTitle(raw_ostream &Stream, const NaClBitcodeDist *Distribution) const { |
| 131 Stream << GetTitle() << " (" << Distribution->size() << " elements):\n\n"; |
| 132 } |
| 133 |
| 134 const char *NaClBitcodeDistElement::GetValueHeader() const { |
| 135 return "Value"; |
| 136 } |
| 137 |
| 138 void NaClBitcodeDistElement::PrintStatsHeader(raw_ostream &Stream) const { |
| 139 Stream << " Count %Count"; |
| 140 } |
| 141 |
| 142 void NaClBitcodeDistElement:: |
| 143 PrintHeader(raw_ostream &Stream) const { |
| 144 PrintStatsHeader(Stream); |
| 145 Stream << " " << GetValueHeader(); |
| 146 } |
| 147 |
| 148 void NaClBitcodeDistElement:: |
| 149 PrintRowStats(raw_ostream &Stream, |
| 150 const NaClBitcodeDist *Distribution) const { |
| 151 unsigned Count = GetNumInstances(); |
| 152 Stream << format("%8d %6.2f", |
| 153 Count, |
| 154 (double) Count/Distribution->GetTotal()*100.0); |
| 155 } |
| 156 |
| 157 void NaClBitcodeDistElement:: |
| 158 PrintRowValue(raw_ostream &Stream, |
| 159 NaClBitcodeDistValue Value, |
| 160 const NaClBitcodeDist *Distribution) const { |
| 161 std::string ValueFormat; |
| 162 raw_string_ostream StrStream(ValueFormat); |
| 163 StrStream << "%" << strlen(GetValueHeader()) << "d"; |
| 164 StrStream.flush(); |
| 165 Stream << format(ValueFormat.c_str(), (int) Value); |
| 166 } |
| 167 |
| 168 void NaClBitcodeDistElement:: |
| 169 PrintRow(raw_ostream &Stream, |
| 170 NaClBitcodeDistValue Value, |
| 171 const NaClBitcodeDist *Distribution) const { |
| 172 PrintRowStats(Stream, Distribution); |
| 173 Stream << " "; |
| 174 PrintRowValue(Stream, Value, Distribution); |
| 175 Stream << "\n"; |
| 176 } |
| 177 |
| 178 const SmallVectorImpl<NaClBitcodeDist*> *NaClBitcodeDistElement:: |
| 179 GetNestedDistributions() const { |
| 180 return 0; |
| 181 } |
| 182 |
| 183 bool NaClBitcodeDistElement:: |
| 184 PrintNestedDistIfApplicable(raw_ostream &Stream, |
| 185 const std::string &Indent) const { |
| 186 bool PrintedNestedDists = false; |
| 187 if (const SmallVectorImpl<NaClBitcodeDist*> *Dists = |
| 188 GetNestedDistributions()) { |
| 189 for (SmallVectorImpl<NaClBitcodeDist*>::const_iterator |
| 190 Iter = Dists->begin(), IterEnd = Dists->end(); |
| 191 Iter != IterEnd; ++Iter) { |
| 192 NaClBitcodeDist *Dist = *Iter; |
| 193 if (!Dist->empty()) { |
| 194 if (!PrintedNestedDists) { |
| 195 PrintedNestedDists = true; |
| 196 Stream << "\n"; |
| 197 } |
| 198 Dist->Print(Stream, Indent + " "); |
| 199 Stream << "\n"; |
| 200 } |
| 201 } |
| 202 } |
| 203 return PrintedNestedDists; |
| 204 } |
OLD | NEW |