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

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

Issue 593563005: [turbofan] basic block profiler (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 2 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
« no previous file with comments | « src/compiler/basic-block-instrumentor.h ('k') | src/compiler/pipeline.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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-instrumentor.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
12 namespace v8 {
13 namespace internal {
14 namespace compiler {
15
16 // Find the first place to insert new nodes in a block that's already been
17 // scheduled that won't upset the register allocator.
18 static NodeVector::iterator FindInsertionPoint(NodeVector* nodes) {
19 NodeVector::iterator i = nodes->begin();
20 for (; i != nodes->end(); ++i) {
21 const Operator* op = (*i)->op();
22 if (OperatorProperties::IsBasicBlockBegin(op)) continue;
23 switch (op->opcode()) {
24 case IrOpcode::kParameter:
25 case IrOpcode::kPhi:
26 case IrOpcode::kEffectPhi:
27 continue;
28 }
29 break;
30 }
31 return i;
32 }
33
34
35 // TODO(dcarney): need to mark code as non-serializable.
36 static const Operator* PointerConstant(CommonOperatorBuilder* common,
37 void* ptr) {
38 return kPointerSize == 8
39 ? common->Int64Constant(reinterpret_cast<intptr_t>(ptr))
40 : common->Int32Constant(
41 static_cast<int32_t>(reinterpret_cast<intptr_t>(ptr)));
42 }
43
44
45 BasicBlockProfiler::Data* BasicBlockInstrumentor::Instrument(
46 CompilationInfo* info, Graph* graph, Schedule* schedule) {
47 // Skip the exit block in profiles, since the register allocator can't handle
48 // it and entry into it means falling off the end of the function anyway.
49 size_t n_blocks = static_cast<size_t>(schedule->RpoBlockCount()) - 1;
50 BasicBlockProfiler::Data* data =
51 info->isolate()->GetOrCreateBasicBlockProfiler()->NewData(n_blocks);
52 // Set the function name.
53 if (!info->shared_info().is_null() &&
54 info->shared_info()->name()->IsString()) {
55 OStringStream os;
56 String::cast(info->shared_info()->name())->PrintUC16(os);
57 data->SetFunctionName(&os);
58 }
59 // Capture the schedule string before instrumentation.
60 {
61 OStringStream os;
62 os << *schedule;
63 data->SetSchedule(&os);
64 }
65 // Add the increment instructions to the start of every block.
66 CommonOperatorBuilder common(graph->zone());
67 Node* zero = graph->NewNode(common.Int32Constant(0));
68 Node* one = graph->NewNode(common.Int32Constant(1));
69 MachineOperatorBuilder machine;
70 BasicBlockVector* blocks = schedule->rpo_order();
71 size_t block_number = 0;
72 for (BasicBlockVector::iterator it = blocks->begin(); block_number < n_blocks;
73 ++it, ++block_number) {
74 BasicBlock* block = (*it);
75 data->SetBlockId(block_number, block->id());
76 // TODO(dcarney): wire effect and control deps for load and store.
77 // Construct increment operation.
78 Node* base = graph->NewNode(
79 PointerConstant(&common, data->GetCounterAddress(block_number)));
80 Node* load = graph->NewNode(machine.Load(kMachUint32), base, zero);
81 Node* inc = graph->NewNode(machine.Int32Add(), load, one);
82 Node* store = graph->NewNode(
83 machine.Store(StoreRepresentation(kMachUint32, kNoWriteBarrier)), base,
84 zero, inc);
85 // Insert the new nodes.
86 static const int kArraySize = 6;
87 Node* to_insert[kArraySize] = {zero, one, base, load, inc, store};
88 int insertion_start = block_number == 0 ? 0 : 2;
89 NodeVector* nodes = &block->nodes_;
90 NodeVector::iterator insertion_point = FindInsertionPoint(nodes);
91 nodes->insert(insertion_point, &to_insert[insertion_start],
92 &to_insert[kArraySize]);
93 // Tell the scheduler about the new nodes.
94 for (int i = insertion_start; i < kArraySize; ++i) {
95 schedule->SetBlockForNode(block, to_insert[i]);
96 }
97 }
98 return data;
99 }
100
101 } // namespace compiler
102 } // namespace internal
103 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/basic-block-instrumentor.h ('k') | src/compiler/pipeline.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698