Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: src/compiler/basic-block-profiler.cc

Issue 593563005: [turbofan] basic block profiler (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/compiler/basic-block-profiler.h"
6 #include "src/compiler/common-operator.h"
7 #include "src/compiler/graph.h"
8 #include "src/compiler/machine-operator.h"
9 #include "src/compiler/operator-properties-inl.h"
10 #include "src/compiler/schedule.h"
11 #include "src/global-handles.h"
12
13 namespace v8 {
14 namespace internal {
15 namespace compiler {
16
17 BasicBlockProfiler::Data::Data(int n_blocks, int* block_ids, uint32_t* counts,
titzer 2014/09/23 14:14:09 Can you make the constructor allocate the block_id
18 OStringStream* function_name,
19 OStringStream* schedule_stream)
20 : n_blocks_(n_blocks),
21 block_ids_(block_ids),
22 counts_(counts),
23 function_name_(function_name),
24 schedule_stream_(schedule_stream),
25 code_stream_(NULL) {}
26
27
28 BasicBlockProfiler::Data::~Data() {
29 delete[] block_ids_;
30 delete[] counts_;
31 delete function_name_;
32 delete schedule_stream_;
33 delete code_stream_;
34 }
35
36
37 void BasicBlockProfiler::Data::SetCode(Handle<Code> code) {
38 DCHECK_EQ(NULL, code_stream_);
39 #if ENABLE_DISASSEMBLER
40 // TODO(dcarney): reenable this once code printing is fixed.
titzer 2014/09/23 14:14:09 What's broken with code printing?
41 // code_stream_ = new OStringStream();
42 // code->Disassemble(NULL, *code_stream_);
43 #endif
44 }
45
46
47 void BasicBlockProfiler::Data::DumpProfilingData() {
titzer 2014/09/23 14:14:09 Can you use OFStream here? It seems to be the way
48 const char* name = "unknown function";
49 if (function_name_ != NULL) {
50 name = function_name_->c_str();
51 }
52 fprintf(stderr, "schedule for %s:\n", name);
53 if (schedule_stream_ != NULL) {
54 fprintf(stderr, "%s\n", schedule_stream_->c_str());
55 }
56 fprintf(stderr, "block counts for %s:\n", name);
57 for (int i = 0; i < n_blocks_; ++i) {
58 fprintf(stderr, "block %d : %u\n", block_ids_[i], counts_[i]);
59 }
60 fprintf(stderr, "\n");
61 if (code_stream_ != NULL) {
62 fprintf(stderr, "%s\n", code_stream_->c_str());
63 }
64 }
65
66
67 void BasicBlockProfiler::Data::ResetCounts() {
68 for (int i = 0; i < n_blocks_; ++i) {
69 counts_[i] = 0;
70 }
71 }
72
73
74 BasicBlockProfiler::BasicBlockProfiler() {}
75
76
77 BasicBlockProfiler::~BasicBlockProfiler() {
78 DumpProfilingData();
79 TearDown();
80 }
81
82
83 void BasicBlockProfiler::TearDown() {
84 for (DataList::iterator i = data_list_.begin(); i != data_list_.end(); ++i) {
85 delete (*i);
86 }
87 data_list_.clear();
88 }
89
90
91 void BasicBlockProfiler::ResetCounts() {
92 for (DataList::iterator i = data_list_.begin(); i != data_list_.end(); ++i) {
93 (*i)->ResetCounts();
94 }
95 }
96
97
98 void BasicBlockProfiler::DumpProfilingData() {
99 fprintf(stderr, "---- Start Profiling Data ----\n");
100 for (DataList::iterator i = data_list_.begin(); i != data_list_.end(); ++i) {
101 (*i)->DumpProfilingData();
102 }
103 fprintf(stderr, "---- End Profiling Data ----\n");
104 }
105
106
107 BasicBlockProfiler::Data* BasicBlockProfiler::Profile(CompilationInfo* info,
108 Graph* graph,
109 Schedule* schedule) {
110 OStringStream* schedule_stream = new OStringStream();
111 (*schedule_stream) << *schedule;
112 int n_blocks = schedule->RpoBlockCount();
113 // Create a backing store for the count data.
114 uint32_t* counts = new uint32_t[n_blocks];
115 for (int i = 0; i < n_blocks; ++i) {
116 counts[i] = 0;
117 }
118 // Add the increment instructions to the start of every block.
119 CommonOperatorBuilder common(graph->zone());
120 intptr_t base_address = reinterpret_cast<intptr_t>(counts);
121 // TODO(dcarney): need to mark code as non-serializable.
122 const Operator* base_op =
123 kPointerSize == 8 ? common.Int64Constant(base_address)
124 : common.Int32Constant(static_cast<int>(base_address));
125 Node* base = graph->NewNode(base_op);
126 Node* one = graph->NewNode(common.Int32Constant(1));
127 MachineOperatorBuilder machine;
128 StoreRepresentation representation(kMachUint32, kNoWriteBarrier);
129 const Operator* load_op = machine.Load(kMachUint32);
130 const Operator* store_op = machine.Store(representation);
131 const Operator* add_op = machine.Int32Add();
132 BasicBlockVector* blocks = schedule->rpo_order();
133 int block_number = 0;
134 int* block_ids = new int[n_blocks];
135 for (BasicBlockVector::iterator it = blocks->begin(); it != blocks->end();
136 ++it, ++block_number) {
137 BasicBlock* block = (*it);
138 block_ids[block_number] = block->id();
titzer 2014/09/23 14:14:09 Pull the body of this loop out into its own functi
139 // Construct increment operation.
140 int index_value = sizeof(counts[0]) * block_number;
141 Node* index = graph->NewNode(common.Int32Constant(index_value));
142 // TODO(dcarney): wire effect and control deps for load and store.
143 Node* load = graph->NewNode(load_op, base, index);
144 Node* inc = graph->NewNode(add_op, load, one);
145 Node* store = graph->NewNode(store_op, base, index, inc);
146 // skip parameters and phis when inserting.
147 NodeVector& nodes = block->nodes_;
148 NodeVector::iterator j = nodes.begin();
149 for (; j != nodes.end(); ++j) {
150 const Operator* op = (*j)->op();
151 if (OperatorProperties::IsBasicBlockBegin(op)) continue;
152 switch (op->opcode()) {
153 case IrOpcode::kParameter:
154 case IrOpcode::kPhi:
155 case IrOpcode::kEffectPhi:
156 continue;
157 }
158 break;
159 }
160 static const int kArraySize = 6;
161 Node* to_insert[kArraySize] = {base, one, index, load, inc, store};
162 int insertion_start = block_number == 0 ? 0 : 2;
163 nodes.insert(j, &to_insert[insertion_start], &to_insert[kArraySize]);
164 for (int j = insertion_start; j < kArraySize; ++j) {
165 schedule->SetBlockForNode(block, to_insert[j]);
166 }
167 }
168 OStringStream* function_name = NULL;
169 if (!info->shared_info().is_null() &&
170 info->shared_info()->name()->IsString()) {
171 function_name = new OStringStream();
172 String::cast(info->shared_info()->name())->PrintUC16(*function_name);
173 }
174 Data* data =
175 new Data(n_blocks, block_ids, counts, function_name, schedule_stream);
176 data_list_.push_back(data);
177 return data;
178 }
179
180 } // namespace compiler
181 } // namespace internal
182 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698