| Index: lib/Bitcode/NaCl/Analysis/NaClBitcodeValueDist.cpp
|
| diff --git a/lib/Bitcode/NaCl/Analysis/NaClBitcodeValueDist.cpp b/lib/Bitcode/NaCl/Analysis/NaClBitcodeValueDist.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e67bebf76cbdaa3468d621407c16d94a9ceb562b
|
| --- /dev/null
|
| +++ b/lib/Bitcode/NaCl/Analysis/NaClBitcodeValueDist.cpp
|
| @@ -0,0 +1,216 @@
|
| +//===-- NaClBitcodeValueDist.cpp ------------------------------------------===//
|
| +// Implements (nested) distribution maps to separate out values at each
|
| +// index in a bitcode record.
|
| +//
|
| +// The LLVM Compiler Infrastructure
|
| +//
|
| +// This file is distributed under the University of Illinois Open Source
|
| +// License. See LICENSE.TXT for details.
|
| +//
|
| +//===----------------------------------------------------------------------===//
|
| +
|
| +#include "llvm/ADT/STLExtras.h"
|
| +#include "llvm/Bitcode/NaCl/NaClBitcodeValueDist.h"
|
| +#include "llvm/Support/DataTypes.h"
|
| +
|
| +using namespace llvm;
|
| +
|
| +/// Constant defining cutoff for value distributions. All values less than
|
| +/// this constant will be stored as a singleton range.
|
| +static NaClBitcodeDistValue ValueDistSingletonCutoff =
|
| + (NaClBitcodeDistValue)1 << 6;
|
| +
|
| +/// Largest value possible.
|
| +static NaClBitcodeDistValue MaxValue = ~((NaClBitcodeDistValue) 0);
|
| +
|
| +/// Cutoffs for value ranges, starting the first range at
|
| +/// ValueDistSingetonCutoff, and ending the last range with MaxValue.
|
| +static NaClBitcodeDistValue ValueCutoffs[] = {
|
| + (NaClBitcodeDistValue)1 << 8,
|
| + (NaClBitcodeDistValue)1 << 12,
|
| + (NaClBitcodeDistValue)1 << 16,
|
| + (NaClBitcodeDistValue)1 << 24,
|
| + (NaClBitcodeDistValue)1 << 32
|
| +};
|
| +
|
| +// Converts the value to the corresponding range (value) that will
|
| +// be stored in a value distribution map.
|
| +NaClValueRangeIndexType
|
| +llvm::GetNaClValueRangeIndex(NaClBitcodeDistValue Value) {
|
| + if (Value < ValueDistSingletonCutoff)
|
| + return Value;
|
| +
|
| + size_t ValueCutoffsSize = array_lengthof(ValueCutoffs);
|
| + for (size_t i = 0; i < ValueCutoffsSize; ++i) {
|
| + if (Value < ValueCutoffs[i]) {
|
| + return ValueDistSingletonCutoff + i;
|
| + }
|
| + }
|
| +
|
| + return ValueDistSingletonCutoff + ValueCutoffsSize;
|
| +}
|
| +
|
| +NaClValueRangeType llvm::GetNaClValueRange(NaClValueRangeIndexType RangeIndex) {
|
| + if (RangeIndex < ValueDistSingletonCutoff)
|
| + return NaClValueRangeType(RangeIndex, RangeIndex);
|
| +
|
| + size_t Index = RangeIndex - ValueDistSingletonCutoff;
|
| + size_t ValueCutoffsSize = array_lengthof(ValueCutoffs);
|
| + if (Index >= ValueCutoffsSize)
|
| + return NaClValueRangeType(ValueCutoffs[ValueCutoffsSize-1], MaxValue);
|
| + else if (Index == 0)
|
| + return NaClValueRangeType(ValueDistSingletonCutoff, ValueCutoffs[0]);
|
| + else
|
| + return NaClValueRangeType(ValueCutoffs[Index-1], ValueCutoffs[Index]-1);
|
| +}
|
| +
|
| +NaClBitcodeValueDistElement NaClBitcodeValueDistElement::Sentinel;
|
| +
|
| +NaClBitcodeValueDistElement::~NaClBitcodeValueDistElement() {}
|
| +
|
| +NaClBitcodeDistElement *NaClBitcodeValueDistElement::CreateElement(
|
| + NaClBitcodeDistValue Value) const {
|
| + return new NaClBitcodeValueDistElement();
|
| +}
|
| +
|
| +double NaClBitcodeValueDistElement::
|
| +GetImportance(NaClBitcodeDistValue Value) const {
|
| + NaClValueRangeType Pair = GetNaClValueRange(Value);
|
| + return GetNumInstances() / static_cast<double>((Pair.second-Pair.first) + 1);
|
| +}
|
| +
|
| +const char *NaClBitcodeValueDistElement::GetTitle() const {
|
| + return "Values";
|
| +}
|
| +
|
| +const char *NaClBitcodeValueDistElement::GetValueHeader() const {
|
| + return "Value / Range";
|
| +}
|
| +
|
| +void NaClBitcodeValueDistElement::
|
| +PrintRowValue(raw_ostream &Stream,
|
| + NaClBitcodeDistValue Value,
|
| + const NaClBitcodeDist *Distribution) const {
|
| + NaClValueRangeType Range = GetNaClValueRange(Value);
|
| + Stream << format("%" PRIu64, Range.first);
|
| + if (Range.first != Range.second) {
|
| + Stream << " .. " << format("%" PRIu64, Range.second);
|
| + }
|
| +}
|
| +
|
| +/// Defines the sentinel distribution element of range indices for untracked
|
| +/// indices in the bitcode records, which need a clarifying print title.
|
| +class NaClBitcodeUntrackedValueDistElement
|
| + : public NaClBitcodeValueDistElement {
|
| +public:
|
| + static NaClBitcodeUntrackedValueDistElement Sentinel;
|
| +
|
| + virtual ~NaClBitcodeUntrackedValueDistElement();
|
| +
|
| + virtual const char *GetTitle() const;
|
| +
|
| +private:
|
| + NaClBitcodeUntrackedValueDistElement()
|
| + : NaClBitcodeValueDistElement()
|
| + {}
|
| +};
|
| +
|
| +NaClBitcodeUntrackedValueDistElement
|
| +NaClBitcodeUntrackedValueDistElement::Sentinel;
|
| +
|
| +NaClBitcodeUntrackedValueDistElement::~NaClBitcodeUntrackedValueDistElement() {}
|
| +
|
| +const char *NaClBitcodeUntrackedValueDistElement::GetTitle() const {
|
| + return "Values for untracked indices";
|
| +}
|
| +
|
| +NaClBitcodeValueDist::
|
| +NaClBitcodeValueDist(unsigned Index, bool AllRemainingIndices)
|
| + : NaClBitcodeDist(RecordStorage,
|
| + (AllRemainingIndices
|
| + ? &NaClBitcodeUntrackedValueDistElement::Sentinel
|
| + : &NaClBitcodeValueDistElement::Sentinel),
|
| + RD_ValueDist),
|
| + Index(Index),
|
| + AllRemainingIndices(AllRemainingIndices) {
|
| +}
|
| +
|
| +NaClBitcodeValueDist::~NaClBitcodeValueDist() {}
|
| +
|
| +void NaClBitcodeValueDist::GetValueList(const NaClBitcodeRecord &Record,
|
| + ValueListType &ValueList) const {
|
| + const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
|
| + if (AllRemainingIndices) {
|
| + for (size_t i = Index, i_limit = Values.size(); i < i_limit; ++i) {
|
| + ValueList.push_back(GetNaClValueRangeIndex(Values[i]));
|
| + }
|
| + } else {
|
| + ValueList.push_back(GetNaClValueRangeIndex(Values[Index]));
|
| + }
|
| +}
|
| +
|
| +NaClBitcodeValueIndexDistElement NaClBitcodeValueIndexDistElement::Sentinel;
|
| +
|
| +NaClBitcodeValueIndexDistElement::~NaClBitcodeValueIndexDistElement() {}
|
| +
|
| +NaClBitcodeDistElement *NaClBitcodeValueIndexDistElement::CreateElement(
|
| + NaClBitcodeDistValue Value) const {
|
| + return new NaClBitcodeValueIndexDistElement(Value);
|
| +}
|
| +
|
| +void NaClBitcodeValueIndexDistElement::
|
| +GetValueList(const NaClBitcodeRecord &Record, ValueListType &ValueList) const {
|
| + unsigned i_limit = Record.GetValues().size();
|
| + if (i_limit > NaClValueIndexCutoff) i_limit = NaClValueIndexCutoff;
|
| + for (size_t i = 0; i < i_limit; ++i) {
|
| + ValueList.push_back(i);
|
| + }
|
| +}
|
| +
|
| +double NaClBitcodeValueIndexDistElement::
|
| +GetImportance(NaClBitcodeDistValue Value) const {
|
| + // Since all indices (usually) have the same number of instances,
|
| + // that is a bad measure of importance. Rather, we will base
|
| + // importance in terms of the value distribution for the value
|
| + // index. We would like the indicies with a few, large instance
|
| + // counts, to appear before value indices with a uniform value
|
| + // distribution. To do this, we will use the sum of the squares of
|
| + // the number of instances for each value (i.e. sort by standard
|
| + // deviation).
|
| + double Sum = 0.0;
|
| + for (NaClBitcodeDist::const_iterator
|
| + Iter = ValueDist.begin(), IterEnd = ValueDist.end();
|
| + Iter != IterEnd; ++Iter) {
|
| + const NaClBitcodeValueDistElement *Elmt =
|
| + cast<NaClBitcodeValueDistElement>(Iter->second);
|
| + double Count = static_cast<double>(Elmt->GetImportance(Iter->first));
|
| + Sum += Count * Count;
|
| + }
|
| + return Sum;
|
| +}
|
| +
|
| +void NaClBitcodeValueIndexDistElement::
|
| +AddRecord(const NaClBitcodeRecord &Record) {
|
| + NaClBitcodeDistElement::AddRecord(Record);
|
| + ValueDist.AddRecord(Record);
|
| +}
|
| +
|
| +const char *NaClBitcodeValueIndexDistElement::GetTitle() const {
|
| + return "Value indices";
|
| +}
|
| +
|
| +const char *NaClBitcodeValueIndexDistElement::GetValueHeader() const {
|
| + return " Index";
|
| +}
|
| +
|
| +void NaClBitcodeValueIndexDistElement::
|
| +PrintRowValue(raw_ostream &Stream,
|
| + NaClBitcodeDistValue Value,
|
| + const NaClBitcodeDist *Distribution) const {
|
| + Stream << format("%7u", Value);
|
| +}
|
| +
|
| +const SmallVectorImpl<NaClBitcodeDist*> *NaClBitcodeValueIndexDistElement::
|
| +GetNestedDistributions() const {
|
| + return &NestedDists;
|
| +}
|
|
|