text.cc revision 7831
1695SN/A/*
21762SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan
3695SN/A * All rights reserved.
4695SN/A *
5695SN/A * Redistribution and use in source and binary forms, with or without
6695SN/A * modification, are permitted provided that the following conditions are
7695SN/A * met: redistributions of source code must retain the above copyright
8695SN/A * notice, this list of conditions and the following disclaimer;
9695SN/A * redistributions in binary form must reproduce the above copyright
10695SN/A * notice, this list of conditions and the following disclaimer in the
11695SN/A * documentation and/or other materials provided with the distribution;
12695SN/A * neither the name of the copyright holders nor the names of its
13695SN/A * contributors may be used to endorse or promote products derived from
14695SN/A * this software without specific prior written permission.
15695SN/A *
16695SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17695SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18695SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19695SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20695SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21695SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22695SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23695SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24695SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25695SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26695SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert
29695SN/A */
30695SN/A
31873SN/A#if defined(__APPLE__)
32873SN/A#define _GLIBCPP_USE_C99 1
33873SN/A#endif
34873SN/A
353918Ssaidi@eecs.umich.edu#if defined(__sun)
363918Ssaidi@eecs.umich.edu#include <math.h>
373918Ssaidi@eecs.umich.edu#endif
383918Ssaidi@eecs.umich.edu
396129Snate@binkert.org#include <cassert>
406129Snate@binkert.org#ifdef __SUNPRO_CC
416129Snate@binkert.org#include <math.h>
426129Snate@binkert.org#endif
436129Snate@binkert.org#include <cmath>
44695SN/A#include <iostream>
452621SN/A#include <sstream>
46695SN/A#include <fstream>
47695SN/A#include <string>
48695SN/A
496129Snate@binkert.org#include "base/cast.hh"
50695SN/A#include "base/misc.hh"
516129Snate@binkert.org#include "base/str.hh"
526129Snate@binkert.org#include "base/stats/info.hh"
53695SN/A#include "base/stats/text.hh"
54695SN/A#include "base/stats/visit.hh"
55695SN/A
56695SN/Ausing namespace std;
57695SN/A
58695SN/A#ifndef NAN
59695SN/Afloat __nan();
60695SN/A/** Define Not a number. */
61695SN/A#define NAN (__nan())
62695SN/A/** Need to define __nan() */
63695SN/A#define __M5_NAN
64695SN/A#endif
65695SN/A
66695SN/A#ifdef __M5_NAN
67695SN/Afloat
68695SN/A__nan()
69695SN/A{
70695SN/A    union {
71695SN/A        uint32_t ui;
72695SN/A        float f;
73695SN/A    } nan;
74695SN/A
75695SN/A    nan.ui = 0x7fc00000;
76695SN/A    return nan.f;
77695SN/A}
78695SN/A#endif
79695SN/A
80729SN/Anamespace Stats {
81695SN/A
826129Snate@binkert.orgstd::list<Info *> &statsList();
836129Snate@binkert.org
84695SN/AText::Text()
856126Snate@binkert.org    : mystream(false), stream(NULL), descriptions(false)
86695SN/A{
87695SN/A}
88695SN/A
89695SN/AText::Text(std::ostream &stream)
906126Snate@binkert.org    : mystream(false), stream(NULL), descriptions(false)
91695SN/A{
92695SN/A    open(stream);
93695SN/A}
94695SN/A
95695SN/AText::Text(const std::string &file)
966126Snate@binkert.org    : mystream(false), stream(NULL), descriptions(false)
97695SN/A{
98695SN/A    open(file);
99695SN/A}
100695SN/A
101695SN/A
102695SN/AText::~Text()
103695SN/A{
104695SN/A    if (mystream) {
105695SN/A        assert(stream);
106695SN/A        delete stream;
107695SN/A    }
108695SN/A}
109695SN/A
110695SN/Avoid
111695SN/AText::open(std::ostream &_stream)
112695SN/A{
113695SN/A    if (stream)
114695SN/A        panic("stream already set!");
115695SN/A
116695SN/A    mystream = false;
117695SN/A    stream = &_stream;
1185581Ssaidi@eecs.umich.edu    if (!valid())
1195581Ssaidi@eecs.umich.edu        fatal("Unable to open output stream for writing\n");
120695SN/A}
121695SN/A
122695SN/Avoid
123695SN/AText::open(const std::string &file)
124695SN/A{
125695SN/A    if (stream)
126695SN/A        panic("stream already set!");
127695SN/A
128695SN/A    mystream = true;
129695SN/A    stream = new ofstream(file.c_str(), ios::trunc);
1305581Ssaidi@eecs.umich.edu    if (!valid())
1315581Ssaidi@eecs.umich.edu        fatal("Unable to open statistics file for writing\n");
132695SN/A}
133695SN/A
134695SN/Abool
135695SN/AText::valid() const
136695SN/A{
1375581Ssaidi@eecs.umich.edu    return stream != NULL && stream->good();
138695SN/A}
139695SN/A
140695SN/Avoid
141695SN/AText::output()
142695SN/A{
143695SN/A    ccprintf(*stream, "\n---------- Begin Simulation Statistics ----------\n");
1445887Snate@binkert.org    list<Info *>::const_iterator i, end = statsList().end();
1455887Snate@binkert.org    for (i = statsList().begin(); i != end; ++i)
1462343SN/A        (*i)->visit(*this);
147695SN/A    ccprintf(*stream, "\n---------- End Simulation Statistics   ----------\n");
148695SN/A    stream->flush();
149695SN/A}
150695SN/A
151695SN/Abool
1525886Snate@binkert.orgText::noOutput(const Info &info)
153695SN/A{
1547462Snate@binkert.org    if (!info.flags.isSet(display))
155695SN/A        return true;
156695SN/A
1575886Snate@binkert.org    if (info.prereq && info.prereq->zero())
158695SN/A        return true;
159695SN/A
160695SN/A    return false;
161695SN/A}
162695SN/A
163695SN/Astring
1646126Snate@binkert.orgValueToString(Result value, int precision)
165695SN/A{
166695SN/A    stringstream val;
167695SN/A
168695SN/A    if (!isnan(value)) {
169695SN/A        if (precision != -1)
170695SN/A            val.precision(precision);
171695SN/A        else if (value == rint(value))
172695SN/A            val.precision(0);
173695SN/A
174695SN/A        val.unsetf(ios::showpoint);
175695SN/A        val.setf(ios::fixed);
176695SN/A        val << value;
177695SN/A    } else {
1786126Snate@binkert.org        val << "no_value";
179695SN/A    }
180695SN/A
181695SN/A    return val.str();
182695SN/A}
183695SN/A
184695SN/Astruct ScalarPrint
185695SN/A{
186695SN/A    Result value;
187695SN/A    string name;
188695SN/A    string desc;
1896130Snate@binkert.org    Flags flags;
190695SN/A    bool descriptions;
191695SN/A    int precision;
192695SN/A    Result pdf;
193695SN/A    Result cdf;
194695SN/A
1956211Snate@binkert.org    void update(Result val, Result total);
196695SN/A    void operator()(ostream &stream) const;
197695SN/A};
198695SN/A
199695SN/Avoid
2006211Snate@binkert.orgScalarPrint::update(Result val, Result total)
2016211Snate@binkert.org{
2026211Snate@binkert.org    value = val;
2036211Snate@binkert.org    if (total) {
2046211Snate@binkert.org        pdf = val / total;
2056211Snate@binkert.org        cdf += pdf;
2066211Snate@binkert.org    }
2076211Snate@binkert.org}
2086211Snate@binkert.org
2096211Snate@binkert.orgvoid
210695SN/AScalarPrint::operator()(ostream &stream) const
211695SN/A{
2126130Snate@binkert.org    if ((flags.isSet(nozero) && value == 0.0) ||
2136130Snate@binkert.org        (flags.isSet(nonan) && isnan(value)))
214695SN/A        return;
215695SN/A
216695SN/A    stringstream pdfstr, cdfstr;
217695SN/A
218695SN/A    if (!isnan(pdf))
219695SN/A        ccprintf(pdfstr, "%.2f%%", pdf * 100.0);
220695SN/A
221695SN/A    if (!isnan(cdf))
222695SN/A        ccprintf(cdfstr, "%.2f%%", cdf * 100.0);
223695SN/A
2246126Snate@binkert.org    ccprintf(stream, "%-40s %12s %10s %10s", name,
2256126Snate@binkert.org             ValueToString(value, precision), pdfstr, cdfstr);
226695SN/A
227695SN/A    if (descriptions) {
228695SN/A        if (!desc.empty())
229695SN/A            ccprintf(stream, " # %s", desc);
230695SN/A    }
231695SN/A    stream << endl;
232695SN/A}
233695SN/A
234695SN/Astruct VectorPrint
235695SN/A{
236695SN/A    string name;
237695SN/A    string desc;
238695SN/A    vector<string> subnames;
239695SN/A    vector<string> subdescs;
2406130Snate@binkert.org    Flags flags;
241695SN/A    bool descriptions;
242695SN/A    int precision;
243695SN/A    VResult vec;
244695SN/A    Result total;
245695SN/A
246695SN/A    void operator()(ostream &stream) const;
247695SN/A};
248695SN/A
249695SN/Avoid
250695SN/AVectorPrint::operator()(std::ostream &stream) const
251695SN/A{
2525599Snate@binkert.org    size_type _size = vec.size();
253695SN/A    Result _total = 0.0;
254695SN/A
2556130Snate@binkert.org    if (flags.isSet(pdf | cdf)) {
2565599Snate@binkert.org        for (off_type i = 0; i < _size; ++i) {
257695SN/A            _total += vec[i];
258695SN/A        }
259695SN/A    }
260695SN/A
2616126Snate@binkert.org    string base = name + "::";
262695SN/A
263695SN/A    ScalarPrint print;
264695SN/A    print.name = name;
265695SN/A    print.desc = desc;
266695SN/A    print.precision = precision;
267695SN/A    print.descriptions = descriptions;
268695SN/A    print.flags = flags;
2696211Snate@binkert.org    print.pdf = _total ? 0.0 : NAN;
2706211Snate@binkert.org    print.cdf = _total ? 0.0 : NAN;
271695SN/A
272695SN/A    bool havesub = !subnames.empty();
273695SN/A
274695SN/A    if (_size == 1) {
275695SN/A        print.value = vec[0];
276695SN/A        print(stream);
2776126Snate@binkert.org        return;
2786126Snate@binkert.org    }
279695SN/A
2806126Snate@binkert.org    for (off_type i = 0; i < _size; ++i) {
2816126Snate@binkert.org        if (havesub && (i >= subnames.size() || subnames[i].empty()))
2826126Snate@binkert.org            continue;
283695SN/A
2846126Snate@binkert.org        print.name = base + (havesub ? subnames[i] : to_string(i));
2856126Snate@binkert.org        print.desc = subdescs.empty() ? desc : subdescs[i];
286695SN/A
2876211Snate@binkert.org        print.update(vec[i], _total);
2886126Snate@binkert.org        print(stream);
2896126Snate@binkert.org    }
290695SN/A
2916130Snate@binkert.org    if (flags.isSet(::Stats::total)) {
2926126Snate@binkert.org        print.pdf = NAN;
2936126Snate@binkert.org        print.cdf = NAN;
2946126Snate@binkert.org        print.name = base + "total";
2956126Snate@binkert.org        print.desc = desc;
2966126Snate@binkert.org        print.value = total;
2976126Snate@binkert.org        print(stream);
298695SN/A    }
299695SN/A}
300695SN/A
301695SN/Astruct DistPrint
302695SN/A{
303695SN/A    string name;
304695SN/A    string desc;
3056130Snate@binkert.org    Flags flags;
306695SN/A    bool descriptions;
307695SN/A    int precision;
308695SN/A
3096004Snate@binkert.org    const DistData &data;
3106004Snate@binkert.org
3116128Snate@binkert.org    DistPrint(const Text *text, const DistInfo &info);
3126128Snate@binkert.org    DistPrint(const Text *text, const VectorDistInfo &info, int i);
3137505Snate@binkert.org    void init(const Text *text, const Info &info);
314695SN/A    void operator()(ostream &stream) const;
315695SN/A};
316695SN/A
3176128Snate@binkert.orgDistPrint::DistPrint(const Text *text, const DistInfo &info)
3186004Snate@binkert.org    : data(info.data)
3196004Snate@binkert.org{
3207505Snate@binkert.org    init(text, info);
3216004Snate@binkert.org}
3226004Snate@binkert.org
3236128Snate@binkert.orgDistPrint::DistPrint(const Text *text, const VectorDistInfo &info, int i)
3246004Snate@binkert.org    : data(info.data[i])
3256004Snate@binkert.org{
3267505Snate@binkert.org    init(text, info);
3276004Snate@binkert.org
3286004Snate@binkert.org    name = info.name + "_" +
3296004Snate@binkert.org        (info.subnames[i].empty() ? (to_string(i)) : info.subnames[i]);
3306004Snate@binkert.org
3316004Snate@binkert.org    if (!info.subdescs[i].empty())
3326004Snate@binkert.org        desc = info.subdescs[i];
3336004Snate@binkert.org}
3346004Snate@binkert.org
3356004Snate@binkert.orgvoid
3367505Snate@binkert.orgDistPrint::init(const Text *text, const Info &info)
3376004Snate@binkert.org{
3386004Snate@binkert.org    name = info.name;
3396004Snate@binkert.org    desc = info.desc;
3406004Snate@binkert.org    flags = info.flags;
3416004Snate@binkert.org    precision = info.precision;
3426125Snate@binkert.org    descriptions = text->descriptions;
3436004Snate@binkert.org}
3446004Snate@binkert.org
345695SN/Avoid
346695SN/ADistPrint::operator()(ostream &stream) const
347695SN/A{
3486126Snate@binkert.org    string base = name + "::";
349695SN/A
350695SN/A    ScalarPrint print;
3516211Snate@binkert.org    print.precision = precision;
352695SN/A    print.flags = flags;
353695SN/A    print.descriptions = descriptions;
3546211Snate@binkert.org    print.desc = desc;
355695SN/A    print.pdf = NAN;
356695SN/A    print.cdf = NAN;
357695SN/A
358695SN/A    print.name = base + "samples";
3596004Snate@binkert.org    print.value = data.samples;
360695SN/A    print(stream);
361695SN/A
3626211Snate@binkert.org    print.name = base + "mean";
3636211Snate@binkert.org    print.value = data.samples ? data.sum / data.samples : NAN;
364695SN/A    print(stream);
365695SN/A
3666211Snate@binkert.org    Result stdev = NAN;
3676211Snate@binkert.org    if (data.samples)
3686211Snate@binkert.org        stdev = sqrt((data.samples * data.squares - data.sum * data.sum) /
3696211Snate@binkert.org                     (data.samples * (data.samples - 1.0)));
3706211Snate@binkert.org    print.name = base + "stdev";
3716211Snate@binkert.org    print.value = stdev;
3726211Snate@binkert.org    print(stream);
3736211Snate@binkert.org
3747505Snate@binkert.org    if (data.type == Deviation)
3756211Snate@binkert.org        return;
3766211Snate@binkert.org
3777505Snate@binkert.org    size_t size = data.cvec.size();
3786211Snate@binkert.org
3796211Snate@binkert.org    Result total = 0.0;
3807831Snate@binkert.org    if (data.type == Dist && data.underflow != NAN)
3816211Snate@binkert.org        total += data.underflow;
3826211Snate@binkert.org    for (off_type i = 0; i < size; ++i)
3836211Snate@binkert.org        total += data.cvec[i];
3847831Snate@binkert.org    if (data.type == Dist && data.overflow != NAN)
3856211Snate@binkert.org        total += data.overflow;
3866211Snate@binkert.org
3876126Snate@binkert.org    if (total) {
3886211Snate@binkert.org        print.pdf = 0.0;
3896211Snate@binkert.org        print.cdf = 0.0;
3906126Snate@binkert.org    }
3916211Snate@binkert.org
3927831Snate@binkert.org    if (data.type == Dist && data.underflow != NAN) {
3936211Snate@binkert.org        print.name = base + "underflows";
3946211Snate@binkert.org        print.update(data.underflow, total);
3956211Snate@binkert.org        print(stream);
3966211Snate@binkert.org    }
3976126Snate@binkert.org
3986126Snate@binkert.org    for (off_type i = 0; i < size; ++i) {
3996126Snate@binkert.org        stringstream namestr;
4006126Snate@binkert.org        namestr << base;
4016126Snate@binkert.org
4027505Snate@binkert.org        Counter low = i * data.bucket_size + data.min;
4037505Snate@binkert.org        Counter high = ::min(low + data.bucket_size - 1.0, data.max);
4046126Snate@binkert.org        namestr << low;
4056126Snate@binkert.org        if (low < high)
4066126Snate@binkert.org            namestr << "-" << high;
4076126Snate@binkert.org
4086126Snate@binkert.org        print.name = namestr.str();
4096211Snate@binkert.org        print.update(data.cvec[i], total);
410695SN/A        print(stream);
411695SN/A    }
412695SN/A
4137831Snate@binkert.org    if (data.type == Dist && data.overflow != NAN) {
4146211Snate@binkert.org        print.name = base + "overflows";
4156211Snate@binkert.org        print.update(data.overflow, total);
4166211Snate@binkert.org        print(stream);
417695SN/A    }
418695SN/A
419695SN/A    print.pdf = NAN;
420695SN/A    print.cdf = NAN;
421695SN/A
4227831Snate@binkert.org    if (data.type == Dist && data.min_val != NAN) {
4236211Snate@binkert.org        print.name = base + "min_value";
4246211Snate@binkert.org        print.value = data.min_val;
4256211Snate@binkert.org        print(stream);
4266211Snate@binkert.org    }
4276211Snate@binkert.org
4287831Snate@binkert.org    if (data.type == Dist && data.max_val != NAN) {
4296211Snate@binkert.org        print.name = base + "max_value";
4306211Snate@binkert.org        print.value = data.max_val;
4316211Snate@binkert.org        print(stream);
4326211Snate@binkert.org    }
4336211Snate@binkert.org
4346126Snate@binkert.org    print.name = base + "total";
4356126Snate@binkert.org    print.value = total;
4366126Snate@binkert.org    print(stream);
437695SN/A}
438695SN/A
439695SN/Avoid
4406128Snate@binkert.orgText::visit(const ScalarInfo &info)
441695SN/A{
4425886Snate@binkert.org    if (noOutput(info))
443695SN/A        return;
444695SN/A
445695SN/A    ScalarPrint print;
4465886Snate@binkert.org    print.value = info.result();
4475886Snate@binkert.org    print.name = info.name;
4485886Snate@binkert.org    print.desc = info.desc;
4495886Snate@binkert.org    print.flags = info.flags;
450695SN/A    print.descriptions = descriptions;
4515886Snate@binkert.org    print.precision = info.precision;
452695SN/A    print.pdf = NAN;
453695SN/A    print.cdf = NAN;
454695SN/A
455695SN/A    print(*stream);
456695SN/A}
457695SN/A
458695SN/Avoid
4596128Snate@binkert.orgText::visit(const VectorInfo &info)
460695SN/A{
4615886Snate@binkert.org    if (noOutput(info))
462695SN/A        return;
463695SN/A
4645886Snate@binkert.org    size_type size = info.size();
465695SN/A    VectorPrint print;
466695SN/A
4675886Snate@binkert.org    print.name = info.name;
4685886Snate@binkert.org    print.desc = info.desc;
4695886Snate@binkert.org    print.flags = info.flags;
470695SN/A    print.descriptions = descriptions;
4715886Snate@binkert.org    print.precision = info.precision;
4725886Snate@binkert.org    print.vec = info.result();
4735886Snate@binkert.org    print.total = info.total();
474695SN/A
4755886Snate@binkert.org    if (!info.subnames.empty()) {
4765599Snate@binkert.org        for (off_type i = 0; i < size; ++i) {
4775886Snate@binkert.org            if (!info.subnames[i].empty()) {
4785886Snate@binkert.org                print.subnames = info.subnames;
479695SN/A                print.subnames.resize(size);
4805599Snate@binkert.org                for (off_type i = 0; i < size; ++i) {
4815886Snate@binkert.org                    if (!info.subnames[i].empty() &&
4825886Snate@binkert.org                        !info.subdescs[i].empty()) {
4835886Snate@binkert.org                        print.subdescs = info.subdescs;
484695SN/A                        print.subdescs.resize(size);
485695SN/A                        break;
486695SN/A                    }
487695SN/A                }
488695SN/A                break;
489695SN/A            }
490695SN/A        }
491695SN/A    }
492695SN/A
493695SN/A    print(*stream);
494695SN/A}
495695SN/A
496695SN/Avoid
4976128Snate@binkert.orgText::visit(const Vector2dInfo &info)
498695SN/A{
4995886Snate@binkert.org    if (noOutput(info))
500695SN/A        return;
501695SN/A
502695SN/A    bool havesub = false;
503695SN/A    VectorPrint print;
504695SN/A
5055886Snate@binkert.org    print.subnames = info.y_subnames;
5065886Snate@binkert.org    print.flags = info.flags;
507695SN/A    print.descriptions = descriptions;
5085886Snate@binkert.org    print.precision = info.precision;
509695SN/A
5105886Snate@binkert.org    if (!info.subnames.empty()) {
5115886Snate@binkert.org        for (off_type i = 0; i < info.x; ++i)
5125886Snate@binkert.org            if (!info.subnames[i].empty())
513695SN/A                havesub = true;
514695SN/A    }
515695SN/A
5165886Snate@binkert.org    VResult tot_vec(info.y);
517695SN/A    Result super_total = 0.0;
5185886Snate@binkert.org    for (off_type i = 0; i < info.x; ++i) {
5195886Snate@binkert.org        if (havesub && (i >= info.subnames.size() || info.subnames[i].empty()))
520695SN/A            continue;
521695SN/A
5225886Snate@binkert.org        off_type iy = i * info.y;
5235886Snate@binkert.org        VResult yvec(info.y);
524695SN/A
525695SN/A        Result total = 0.0;
5265886Snate@binkert.org        for (off_type j = 0; j < info.y; ++j) {
5275886Snate@binkert.org            yvec[j] = info.cvec[iy + j];
528695SN/A            tot_vec[j] += yvec[j];
529695SN/A            total += yvec[j];
530695SN/A            super_total += yvec[j];
531695SN/A        }
532695SN/A
5335886Snate@binkert.org        print.name = info.name + "_" +
5345886Snate@binkert.org            (havesub ? info.subnames[i] : to_string(i));
5355886Snate@binkert.org        print.desc = info.desc;
536695SN/A        print.vec = yvec;
537695SN/A        print.total = total;
538695SN/A        print(*stream);
539695SN/A    }
540695SN/A
5416130Snate@binkert.org    if (info.flags.isSet(::Stats::total) && (info.x > 1)) {
5425886Snate@binkert.org        print.name = info.name;
5435886Snate@binkert.org        print.desc = info.desc;
544695SN/A        print.vec = tot_vec;
545695SN/A        print.total = super_total;
546695SN/A        print(*stream);
547695SN/A    }
548695SN/A}
549695SN/A
550695SN/Avoid
5516128Snate@binkert.orgText::visit(const DistInfo &info)
552695SN/A{
5535886Snate@binkert.org    if (noOutput(info))
554695SN/A        return;
555695SN/A
5566125Snate@binkert.org    DistPrint print(this, info);
557695SN/A    print(*stream);
558695SN/A}
559695SN/A
560695SN/Avoid
5616128Snate@binkert.orgText::visit(const VectorDistInfo &info)
562695SN/A{
5635886Snate@binkert.org    if (noOutput(info))
564695SN/A        return;
565695SN/A
5665886Snate@binkert.org    for (off_type i = 0; i < info.size(); ++i) {
5676125Snate@binkert.org        DistPrint print(this, info, i);
568695SN/A        print(*stream);
569695SN/A    }
570695SN/A}
571695SN/A
572695SN/Avoid
5736128Snate@binkert.orgText::visit(const FormulaInfo &info)
574695SN/A{
5756128Snate@binkert.org    visit((const VectorInfo &)info);
576695SN/A}
577695SN/A
5784078Sbinkertn@umich.edubool
5796126Snate@binkert.orginitText(const string &filename, bool desc)
5804078Sbinkertn@umich.edu{
5814078Sbinkertn@umich.edu    static Text text;
5824078Sbinkertn@umich.edu    static bool connected = false;
5834078Sbinkertn@umich.edu
5844078Sbinkertn@umich.edu    if (connected)
5854078Sbinkertn@umich.edu        return false;
5864078Sbinkertn@umich.edu
5874078Sbinkertn@umich.edu    extern list<Output *> OutputList;
5884078Sbinkertn@umich.edu
5894078Sbinkertn@umich.edu    text.open(*simout.find(filename));
5904078Sbinkertn@umich.edu    text.descriptions = desc;
5914078Sbinkertn@umich.edu    OutputList.push_back(&text);
5924078Sbinkertn@umich.edu    connected = true;
5934078Sbinkertn@umich.edu
5944078Sbinkertn@umich.edu    return true;
5954078Sbinkertn@umich.edu}
5964078Sbinkertn@umich.edu
5977811Ssteve.reinhardt@amd.com} // namespace Stats
598