| Index: lib/Bitcode/NaCl/Analysis/NaClBitcodeDist.cpp
|
| diff --git a/lib/Bitcode/NaCl/Analysis/NaClBitcodeDist.cpp b/lib/Bitcode/NaCl/Analysis/NaClBitcodeDist.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..fac862dc5235795d3be90e7313cac0201857703e
|
| --- /dev/null
|
| +++ b/lib/Bitcode/NaCl/Analysis/NaClBitcodeDist.cpp
|
| @@ -0,0 +1,204 @@
|
| +//===- NaClBitcodeDist.cpp --------------------------------------*- C++ -*-===//
|
| +// Internal implementation of PNaCl bitcode distributions.
|
| +//
|
| +// The LLVM Compiler Infrastructure
|
| +//
|
| +// This file is distributed under the University of Illinois Open Source
|
| +// License. See LICENSE.TXT for details.
|
| +//
|
| +//===----------------------------------------------------------------------===//
|
| +
|
| +#include "llvm/Bitcode/NaCl/NaClBitcodeDist.h"
|
| +
|
| +using namespace llvm;
|
| +
|
| +NaClBitcodeDist::~NaClBitcodeDist() {
|
| + RemoveCachedDistribution();
|
| + for (const_iterator Iter = begin(), IterEnd = end();
|
| + Iter != IterEnd; ++Iter) {
|
| + delete Iter->second;
|
| + }
|
| +}
|
| +
|
| +NaClBitcodeDistElement *NaClBitcodeDist::CreateElement(
|
| + NaClBitcodeDistValue Value) const {
|
| + return Sentinel->CreateElement(Value);
|
| +}
|
| +
|
| +void NaClBitcodeDist::GetValueList(const NaClBitcodeRecord &Record,
|
| + ValueListType &ValueList) const {
|
| + Sentinel->GetValueList(Record, ValueList);
|
| +}
|
| +
|
| +void NaClBitcodeDist::AddRecord(const NaClBitcodeRecord &Record) {
|
| + if (StorageKind != NaClBitcodeDist::RecordStorage)
|
| + return;
|
| + ValueListType ValueList;
|
| + GetValueList(Record, ValueList);
|
| + if (!ValueList.empty()) {
|
| + RemoveCachedDistribution();
|
| + for (ValueListIterator
|
| + Iter = ValueList.begin(),
|
| + IterEnd = ValueList.end();
|
| + Iter != IterEnd; ++Iter) {
|
| + NaClBitcodeDistElement *Element = GetElement(*Iter);
|
| + Element->AddRecord(Record);
|
| + ++Total;
|
| + }
|
| + }
|
| +}
|
| +
|
| +void NaClBitcodeDist::AddBlock(const NaClBitcodeBlock &Block) {
|
| + if (StorageKind != NaClBitcodeDist::BlockStorage)
|
| + return;
|
| + RemoveCachedDistribution();
|
| + ++Total;
|
| + unsigned BlockID = Block.GetBlockID();
|
| + NaClBitcodeDistElement *Element = GetElement(BlockID);
|
| + Element->AddBlock(Block);
|
| +}
|
| +
|
| +void NaClBitcodeDist::Print(raw_ostream &Stream,
|
| + const std::string &Indent) const {
|
| + const Distribution *Dist = GetDistribution();
|
| + Stream << Indent;
|
| + Sentinel->PrintTitle(Stream, this);
|
| + Stream << Indent;
|
| + Sentinel->PrintHeader(Stream);
|
| + Stream << "\n";
|
| + bool NeedsHeader = false;
|
| + for (size_t I = 0, E = Dist->size(); I < E; ++I) {
|
| + if (NeedsHeader) {
|
| + // Reprint the header so that rows are more readable.
|
| + Stream << Indent << " " << Sentinel->GetTitle() << " (continued)\n";
|
| + Stream << Indent;
|
| + Sentinel->PrintHeader(Stream);
|
| + Stream << "\n";
|
| + }
|
| + const DistPair &Pair = Dist->at(I);
|
| + Stream << Indent;
|
| + NaClBitcodeDistElement *Element = at(Pair.second);
|
| + Element->PrintRow(Stream, Pair.second, this);
|
| + NeedsHeader = Element->PrintNestedDistIfApplicable(Stream, Indent);
|
| + }
|
| +}
|
| +
|
| +void NaClBitcodeDist::Sort() const {
|
| + RemoveCachedDistribution();
|
| + CachedDistribution = new Distribution();
|
| + for (const_iterator Iter = begin(), IterEnd = end();
|
| + Iter != IterEnd; ++Iter) {
|
| + const NaClBitcodeDistElement *Elmt = Iter->second;
|
| + // Only add if histogram element is non-empty.
|
| + if (Elmt->GetNumInstances()) {
|
| + double Importance = Elmt->GetImportance(Iter->first);
|
| + CachedDistribution->push_back(std::make_pair(Importance, Iter->first));
|
| + }
|
| + }
|
| + // Sort in ascending order, based on importance.
|
| + std::stable_sort(CachedDistribution->begin(),
|
| + CachedDistribution->end());
|
| + // Reverse so most important appear first.
|
| + std::reverse(CachedDistribution->begin(),
|
| + CachedDistribution->end());
|
| +}
|
| +
|
| +NaClBitcodeDistElement::~NaClBitcodeDistElement() {}
|
| +
|
| +void NaClBitcodeDistElement::AddRecord(const NaClBitcodeRecord &Record) {
|
| + ++NumInstances;
|
| +}
|
| +
|
| +void NaClBitcodeDistElement::AddBlock(const NaClBitcodeBlock &Block) {
|
| + ++NumInstances;
|
| +}
|
| +
|
| +void NaClBitcodeDistElement::GetValueList(const NaClBitcodeRecord &Record,
|
| + ValueListType &ValueList) const {
|
| + // By default, assume no record values are defined.
|
| +}
|
| +
|
| +double NaClBitcodeDistElement::GetImportance(NaClBitcodeDistValue Value) const {
|
| + return static_cast<double>(NumInstances);
|
| +}
|
| +
|
| +const char *NaClBitcodeDistElement::GetTitle() const {
|
| + return "Distribution";
|
| +}
|
| +
|
| +void NaClBitcodeDistElement::
|
| +PrintTitle(raw_ostream &Stream, const NaClBitcodeDist *Distribution) const {
|
| + Stream << GetTitle() << " (" << Distribution->size() << " elements):\n\n";
|
| +}
|
| +
|
| +const char *NaClBitcodeDistElement::GetValueHeader() const {
|
| + return "Value";
|
| +}
|
| +
|
| +void NaClBitcodeDistElement::PrintStatsHeader(raw_ostream &Stream) const {
|
| + Stream << " Count %Count";
|
| +}
|
| +
|
| +void NaClBitcodeDistElement::
|
| +PrintHeader(raw_ostream &Stream) const {
|
| + PrintStatsHeader(Stream);
|
| + Stream << " " << GetValueHeader();
|
| +}
|
| +
|
| +void NaClBitcodeDistElement::
|
| +PrintRowStats(raw_ostream &Stream,
|
| + const NaClBitcodeDist *Distribution) const {
|
| + unsigned Count = GetNumInstances();
|
| + Stream << format("%8d %6.2f",
|
| + Count,
|
| + (double) Count/Distribution->GetTotal()*100.0);
|
| +}
|
| +
|
| +void NaClBitcodeDistElement::
|
| +PrintRowValue(raw_ostream &Stream,
|
| + NaClBitcodeDistValue Value,
|
| + const NaClBitcodeDist *Distribution) const {
|
| + std::string ValueFormat;
|
| + raw_string_ostream StrStream(ValueFormat);
|
| + StrStream << "%" << strlen(GetValueHeader()) << "d";
|
| + StrStream.flush();
|
| + Stream << format(ValueFormat.c_str(), (int) Value);
|
| +}
|
| +
|
| +void NaClBitcodeDistElement::
|
| +PrintRow(raw_ostream &Stream,
|
| + NaClBitcodeDistValue Value,
|
| + const NaClBitcodeDist *Distribution) const {
|
| + PrintRowStats(Stream, Distribution);
|
| + Stream << " ";
|
| + PrintRowValue(Stream, Value, Distribution);
|
| + Stream << "\n";
|
| +}
|
| +
|
| +const SmallVectorImpl<NaClBitcodeDist*> *NaClBitcodeDistElement::
|
| +GetNestedDistributions() const {
|
| + return 0;
|
| +}
|
| +
|
| +bool NaClBitcodeDistElement::
|
| +PrintNestedDistIfApplicable(raw_ostream &Stream,
|
| + const std::string &Indent) const {
|
| + bool PrintedNestedDists = false;
|
| + if (const SmallVectorImpl<NaClBitcodeDist*> *Dists =
|
| + GetNestedDistributions()) {
|
| + for (SmallVectorImpl<NaClBitcodeDist*>::const_iterator
|
| + Iter = Dists->begin(), IterEnd = Dists->end();
|
| + Iter != IterEnd; ++Iter) {
|
| + NaClBitcodeDist *Dist = *Iter;
|
| + if (!Dist->empty()) {
|
| + if (!PrintedNestedDists) {
|
| + PrintedNestedDists = true;
|
| + Stream << "\n";
|
| + }
|
| + Dist->Print(Stream, Indent + " ");
|
| + Stream << "\n";
|
| + }
|
| + }
|
| + }
|
| + return PrintedNestedDists;
|
| +}
|
|
|