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

Side by Side Diff: src/compiler/instruction-selector.cc

Issue 889843003: [turbofan] Don't allocate UnallocatedOperands in Zone memory during instruction selection (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 10 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
« no previous file with comments | « src/compiler/instruction-selector.h ('k') | src/compiler/instruction-selector-impl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/instruction-selector.h" 5 #include "src/compiler/instruction-selector.h"
6 6
7 #include "src/compiler/instruction-selector-impl.h" 7 #include "src/compiler/instruction-selector-impl.h"
8 #include "src/compiler/node-matchers.h" 8 #include "src/compiler/node-matchers.h"
9 #include "src/compiler/node-properties.h" 9 #include "src/compiler/node-properties.h"
10 #include "src/compiler/pipeline.h" 10 #include "src/compiler/pipeline.h"
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 sequence()->StartBlock(block->GetRpoNumber()); 66 sequence()->StartBlock(block->GetRpoNumber());
67 while (start-- > end) { 67 while (start-- > end) {
68 sequence()->AddInstruction(instructions_[start]); 68 sequence()->AddInstruction(instructions_[start]);
69 } 69 }
70 sequence()->EndBlock(block->GetRpoNumber()); 70 sequence()->EndBlock(block->GetRpoNumber());
71 } 71 }
72 } 72 }
73 73
74 74
75 Instruction* InstructionSelector::Emit(InstructionCode opcode, 75 Instruction* InstructionSelector::Emit(InstructionCode opcode,
76 InstructionOperand* output, 76 InstructionOperand output,
77 size_t temp_count, 77 size_t temp_count,
78 InstructionOperand** temps) { 78 InstructionOperand* temps) {
79 size_t output_count = output == NULL ? 0 : 1; 79 size_t output_count = output.IsInvalid() ? 0 : 1;
80 return Emit(opcode, output_count, &output, 0, NULL, temp_count, temps); 80 return Emit(opcode, output_count, &output, 0, NULL, temp_count, temps);
81 } 81 }
82 82
83 83
84 Instruction* InstructionSelector::Emit(InstructionCode opcode, 84 Instruction* InstructionSelector::Emit(InstructionCode opcode,
85 InstructionOperand* output, 85 InstructionOperand output,
86 InstructionOperand* a, size_t temp_count, 86 InstructionOperand a, size_t temp_count,
87 InstructionOperand** temps) { 87 InstructionOperand* temps) {
88 size_t output_count = output == NULL ? 0 : 1; 88 size_t output_count = output.IsInvalid() ? 0 : 1;
89 return Emit(opcode, output_count, &output, 1, &a, temp_count, temps); 89 return Emit(opcode, output_count, &output, 1, &a, temp_count, temps);
90 } 90 }
91 91
92 92
93 Instruction* InstructionSelector::Emit(InstructionCode opcode, 93 Instruction* InstructionSelector::Emit(InstructionCode opcode,
94 InstructionOperand* output, 94 InstructionOperand output,
95 InstructionOperand* a, 95 InstructionOperand a,
96 InstructionOperand* b, size_t temp_count, 96 InstructionOperand b, size_t temp_count,
97 InstructionOperand** temps) { 97 InstructionOperand* temps) {
98 size_t output_count = output == NULL ? 0 : 1; 98 size_t output_count = output.IsInvalid() ? 0 : 1;
99 InstructionOperand* inputs[] = {a, b}; 99 InstructionOperand inputs[] = {a, b};
100 size_t input_count = arraysize(inputs); 100 size_t input_count = arraysize(inputs);
101 return Emit(opcode, output_count, &output, input_count, inputs, temp_count, 101 return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
102 temps); 102 temps);
103 } 103 }
104 104
105 105
106 Instruction* InstructionSelector::Emit(InstructionCode opcode, 106 Instruction* InstructionSelector::Emit(InstructionCode opcode,
107 InstructionOperand* output, 107 InstructionOperand output,
108 InstructionOperand* a, 108 InstructionOperand a,
109 InstructionOperand* b, 109 InstructionOperand b,
110 InstructionOperand* c, size_t temp_count, 110 InstructionOperand c, size_t temp_count,
111 InstructionOperand** temps) { 111 InstructionOperand* temps) {
112 size_t output_count = output == NULL ? 0 : 1; 112 size_t output_count = output.IsInvalid() ? 0 : 1;
113 InstructionOperand* inputs[] = {a, b, c}; 113 InstructionOperand inputs[] = {a, b, c};
114 size_t input_count = arraysize(inputs); 114 size_t input_count = arraysize(inputs);
115 return Emit(opcode, output_count, &output, input_count, inputs, temp_count, 115 return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
116 temps); 116 temps);
117 } 117 }
118 118
119 119
120 Instruction* InstructionSelector::Emit( 120 Instruction* InstructionSelector::Emit(
121 InstructionCode opcode, InstructionOperand* output, InstructionOperand* a, 121 InstructionCode opcode, InstructionOperand output, InstructionOperand a,
122 InstructionOperand* b, InstructionOperand* c, InstructionOperand* d, 122 InstructionOperand b, InstructionOperand c, InstructionOperand d,
123 size_t temp_count, InstructionOperand** temps) { 123 size_t temp_count, InstructionOperand* temps) {
124 size_t output_count = output == NULL ? 0 : 1; 124 size_t output_count = output.IsInvalid() ? 0 : 1;
125 InstructionOperand* inputs[] = {a, b, c, d}; 125 InstructionOperand inputs[] = {a, b, c, d};
126 size_t input_count = arraysize(inputs); 126 size_t input_count = arraysize(inputs);
127 return Emit(opcode, output_count, &output, input_count, inputs, temp_count, 127 return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
128 temps); 128 temps);
129 } 129 }
130 130
131 131
132 Instruction* InstructionSelector::Emit( 132 Instruction* InstructionSelector::Emit(
133 InstructionCode opcode, InstructionOperand* output, InstructionOperand* a, 133 InstructionCode opcode, InstructionOperand output, InstructionOperand a,
134 InstructionOperand* b, InstructionOperand* c, InstructionOperand* d, 134 InstructionOperand b, InstructionOperand c, InstructionOperand d,
135 InstructionOperand* e, size_t temp_count, InstructionOperand** temps) { 135 InstructionOperand e, size_t temp_count, InstructionOperand* temps) {
136 size_t output_count = output == NULL ? 0 : 1; 136 size_t output_count = output.IsInvalid() ? 0 : 1;
137 InstructionOperand* inputs[] = {a, b, c, d, e}; 137 InstructionOperand inputs[] = {a, b, c, d, e};
138 size_t input_count = arraysize(inputs); 138 size_t input_count = arraysize(inputs);
139 return Emit(opcode, output_count, &output, input_count, inputs, temp_count, 139 return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
140 temps); 140 temps);
141 } 141 }
142 142
143 143
144 Instruction* InstructionSelector::Emit( 144 Instruction* InstructionSelector::Emit(
145 InstructionCode opcode, InstructionOperand* output, InstructionOperand* a, 145 InstructionCode opcode, InstructionOperand output, InstructionOperand a,
146 InstructionOperand* b, InstructionOperand* c, InstructionOperand* d, 146 InstructionOperand b, InstructionOperand c, InstructionOperand d,
147 InstructionOperand* e, InstructionOperand* f, size_t temp_count, 147 InstructionOperand e, InstructionOperand f, size_t temp_count,
148 InstructionOperand** temps) { 148 InstructionOperand* temps) {
149 size_t output_count = output == NULL ? 0 : 1; 149 size_t output_count = output.IsInvalid() ? 0 : 1;
150 InstructionOperand* inputs[] = {a, b, c, d, e, f}; 150 InstructionOperand inputs[] = {a, b, c, d, e, f};
151 size_t input_count = arraysize(inputs); 151 size_t input_count = arraysize(inputs);
152 return Emit(opcode, output_count, &output, input_count, inputs, temp_count, 152 return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
153 temps); 153 temps);
154 } 154 }
155 155
156 156
157 Instruction* InstructionSelector::Emit( 157 Instruction* InstructionSelector::Emit(
158 InstructionCode opcode, size_t output_count, InstructionOperand** outputs, 158 InstructionCode opcode, size_t output_count, InstructionOperand* outputs,
159 size_t input_count, InstructionOperand** inputs, size_t temp_count, 159 size_t input_count, InstructionOperand* inputs, size_t temp_count,
160 InstructionOperand** temps) { 160 InstructionOperand* temps) {
161 Instruction* instr = 161 Instruction* instr =
162 Instruction::New(instruction_zone(), opcode, output_count, outputs, 162 Instruction::New(instruction_zone(), opcode, output_count, outputs,
163 input_count, inputs, temp_count, temps); 163 input_count, inputs, temp_count, temps);
164 return Emit(instr); 164 return Emit(instr);
165 } 165 }
166 166
167 167
168 Instruction* InstructionSelector::Emit(Instruction* instr) { 168 Instruction* InstructionSelector::Emit(Instruction* instr) {
169 instructions_.push_back(instr); 169 instructions_.push_back(instr);
170 return instr; 170 return instr;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 264
265 265
266 void InstructionSelector::MarkAsReference(Node* node) { 266 void InstructionSelector::MarkAsReference(Node* node) {
267 DCHECK_NOT_NULL(node); 267 DCHECK_NOT_NULL(node);
268 DCHECK(!IsDouble(node)); 268 DCHECK(!IsDouble(node));
269 sequence()->MarkAsReference(GetVirtualRegister(node)); 269 sequence()->MarkAsReference(GetVirtualRegister(node));
270 } 270 }
271 271
272 272
273 void InstructionSelector::MarkAsRepresentation(MachineType rep, 273 void InstructionSelector::MarkAsRepresentation(MachineType rep,
274 InstructionOperand* op) { 274 const InstructionOperand& op) {
275 UnallocatedOperand* unalloc = UnallocatedOperand::cast(op); 275 UnallocatedOperand unalloc = UnallocatedOperand::cast(op);
276 switch (RepresentationOf(rep)) { 276 switch (RepresentationOf(rep)) {
277 case kRepFloat32: 277 case kRepFloat32:
278 case kRepFloat64: 278 case kRepFloat64:
279 sequence()->MarkAsDouble(unalloc->virtual_register()); 279 sequence()->MarkAsDouble(unalloc.virtual_register());
280 break; 280 break;
281 case kRepTagged: 281 case kRepTagged:
282 sequence()->MarkAsReference(unalloc->virtual_register()); 282 sequence()->MarkAsReference(unalloc.virtual_register());
283 break; 283 break;
284 default: 284 default:
285 break; 285 break;
286 } 286 }
287 } 287 }
288 288
289 289
290 void InstructionSelector::MarkAsRepresentation(MachineType rep, Node* node) { 290 void InstructionSelector::MarkAsRepresentation(MachineType rep, Node* node) {
291 DCHECK_NOT_NULL(node); 291 DCHECK_NOT_NULL(node);
292 switch (RepresentationOf(rep)) { 292 switch (RepresentationOf(rep)) {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 for (size_t i = 0; i < buffer->output_nodes.size(); i++) { 356 for (size_t i = 0; i < buffer->output_nodes.size(); i++) {
357 bool output_is_live = 357 bool output_is_live =
358 buffer->output_nodes[i] != NULL || i < outputs_needed_by_framestate; 358 buffer->output_nodes[i] != NULL || i < outputs_needed_by_framestate;
359 if (output_is_live) { 359 if (output_is_live) {
360 MachineType type = 360 MachineType type =
361 buffer->descriptor->GetReturnType(static_cast<int>(i)); 361 buffer->descriptor->GetReturnType(static_cast<int>(i));
362 LinkageLocation location = 362 LinkageLocation location =
363 buffer->descriptor->GetReturnLocation(static_cast<int>(i)); 363 buffer->descriptor->GetReturnLocation(static_cast<int>(i));
364 364
365 Node* output = buffer->output_nodes[i]; 365 Node* output = buffer->output_nodes[i];
366 InstructionOperand* op = 366 InstructionOperand op =
367 output == NULL ? g.TempLocation(location, type) 367 output == NULL ? g.TempLocation(location, type)
368 : g.DefineAsLocation(output, location, type); 368 : g.DefineAsLocation(output, location, type);
369 MarkAsRepresentation(type, op); 369 MarkAsRepresentation(type, op);
370 370
371 buffer->outputs.push_back(op); 371 buffer->outputs.push_back(op);
372 } 372 }
373 } 373 }
374 } 374 }
375 375
376 // The first argument is always the callee code. 376 // The first argument is always the callee code.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 // Split the arguments into pushed_nodes and instruction_args. Pushed 420 // Split the arguments into pushed_nodes and instruction_args. Pushed
421 // arguments require an explicit push instruction before the call and do 421 // arguments require an explicit push instruction before the call and do
422 // not appear as arguments to the call. Everything else ends up 422 // not appear as arguments to the call. Everything else ends up
423 // as an InstructionOperand argument to the call. 423 // as an InstructionOperand argument to the call.
424 auto iter(call->inputs().begin()); 424 auto iter(call->inputs().begin());
425 int pushed_count = 0; 425 int pushed_count = 0;
426 for (size_t index = 0; index < input_count; ++iter, ++index) { 426 for (size_t index = 0; index < input_count; ++iter, ++index) {
427 DCHECK(iter != call->inputs().end()); 427 DCHECK(iter != call->inputs().end());
428 DCHECK((*iter)->op()->opcode() != IrOpcode::kFrameState); 428 DCHECK((*iter)->op()->opcode() != IrOpcode::kFrameState);
429 if (index == 0) continue; // The first argument (callee) is already done. 429 if (index == 0) continue; // The first argument (callee) is already done.
430 InstructionOperand* op = 430 InstructionOperand op =
431 g.UseLocation(*iter, buffer->descriptor->GetInputLocation(index), 431 g.UseLocation(*iter, buffer->descriptor->GetInputLocation(index),
432 buffer->descriptor->GetInputType(index)); 432 buffer->descriptor->GetInputType(index));
433 if (UnallocatedOperand::cast(op)->HasFixedSlotPolicy()) { 433 if (UnallocatedOperand::cast(op).HasFixedSlotPolicy()) {
434 int stack_index = -UnallocatedOperand::cast(op)->fixed_slot_index() - 1; 434 int stack_index = -UnallocatedOperand::cast(op).fixed_slot_index() - 1;
435 if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) { 435 if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) {
436 buffer->pushed_nodes.resize(stack_index + 1, NULL); 436 buffer->pushed_nodes.resize(stack_index + 1, NULL);
437 } 437 }
438 DCHECK(!buffer->pushed_nodes[stack_index]); 438 DCHECK(!buffer->pushed_nodes[stack_index]);
439 buffer->pushed_nodes[stack_index] = *iter; 439 buffer->pushed_nodes[stack_index] = *iter;
440 pushed_count++; 440 pushed_count++;
441 } else { 441 } else {
442 buffer->instruction_args.push_back(op); 442 buffer->instruction_args.push_back(op);
443 } 443 }
444 } 444 }
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 // We must emit a NOP here because every live range needs a defining 1027 // We must emit a NOP here because every live range needs a defining
1028 // instruction in the register allocator. 1028 // instruction in the register allocator.
1029 OperandGenerator g(this); 1029 OperandGenerator g(this);
1030 Emit(kArchNop, g.DefineAsConstant(node)); 1030 Emit(kArchNop, g.DefineAsConstant(node));
1031 } 1031 }
1032 1032
1033 1033
1034 void InstructionSelector::VisitGoto(BasicBlock* target) { 1034 void InstructionSelector::VisitGoto(BasicBlock* target) {
1035 // jump to the next block. 1035 // jump to the next block.
1036 OperandGenerator g(this); 1036 OperandGenerator g(this);
1037 Emit(kArchJmp, NULL, g.Label(target))->MarkAsControl(); 1037 Emit(kArchJmp, g.NoOutput(), g.Label(target))->MarkAsControl();
1038 } 1038 }
1039 1039
1040 1040
1041 void InstructionSelector::VisitReturn(Node* value) { 1041 void InstructionSelector::VisitReturn(Node* value) {
1042 OperandGenerator g(this); 1042 OperandGenerator g(this);
1043 if (value != NULL) { 1043 if (value != NULL) {
1044 Emit(kArchRet, NULL, g.UseLocation(value, linkage()->GetReturnLocation(), 1044 Emit(kArchRet, g.NoOutput(),
1045 linkage()->GetReturnType())); 1045 g.UseLocation(value, linkage()->GetReturnLocation(),
1046 linkage()->GetReturnType()));
1046 } else { 1047 } else {
1047 Emit(kArchRet, NULL); 1048 Emit(kArchRet, g.NoOutput());
1048 } 1049 }
1049 } 1050 }
1050 1051
1051 1052
1052 void InstructionSelector::VisitThrow(Node* value) { 1053 void InstructionSelector::VisitThrow(Node* value) {
1053 Emit(kArchNop, NULL); // TODO(titzer) 1054 OperandGenerator g(this);
1055 Emit(kArchNop, g.NoOutput()); // TODO(titzer)
1054 } 1056 }
1055 1057
1056 1058
1057 void InstructionSelector::FillTypeVectorFromStateValues( 1059 void InstructionSelector::FillTypeVectorFromStateValues(
1058 ZoneVector<MachineType>* types, Node* state_values) { 1060 ZoneVector<MachineType>* types, Node* state_values) {
1059 DCHECK(state_values->opcode() == IrOpcode::kStateValues); 1061 DCHECK(state_values->opcode() == IrOpcode::kStateValues);
1060 int count = state_values->InputCount(); 1062 int count = state_values->InputCount();
1061 types->reserve(static_cast<size_t>(count)); 1063 types->reserve(static_cast<size_t>(count));
1062 for (int i = 0; i < count; i++) { 1064 for (int i = 0; i < count; i++) {
1063 types->push_back(GetMachineType(state_values->InputAt(i))); 1065 types->push_back(GetMachineType(state_values->InputAt(i)));
(...skipping 18 matching lines...) Expand all
1082 Node* outer_node = state->InputAt(4); 1084 Node* outer_node = state->InputAt(4);
1083 if (outer_node->opcode() == IrOpcode::kFrameState) { 1085 if (outer_node->opcode() == IrOpcode::kFrameState) {
1084 outer_state = GetFrameStateDescriptor(outer_node); 1086 outer_state = GetFrameStateDescriptor(outer_node);
1085 } 1087 }
1086 1088
1087 return new (instruction_zone()) FrameStateDescriptor( 1089 return new (instruction_zone()) FrameStateDescriptor(
1088 instruction_zone(), state_info, parameters, locals, stack, outer_state); 1090 instruction_zone(), state_info, parameters, locals, stack, outer_state);
1089 } 1091 }
1090 1092
1091 1093
1092 static InstructionOperand* UseOrImmediate(OperandGenerator* g, Node* input) { 1094 static InstructionOperand UseOrImmediate(OperandGenerator* g, Node* input) {
1093 switch (input->opcode()) { 1095 switch (input->opcode()) {
1094 case IrOpcode::kInt32Constant: 1096 case IrOpcode::kInt32Constant:
1095 case IrOpcode::kNumberConstant: 1097 case IrOpcode::kNumberConstant:
1096 case IrOpcode::kFloat64Constant: 1098 case IrOpcode::kFloat64Constant:
1097 case IrOpcode::kHeapConstant: 1099 case IrOpcode::kHeapConstant:
1098 return g->UseImmediate(input); 1100 return g->UseImmediate(input);
1099 default: 1101 default:
1100 return g->UseUnique(input); 1102 return g->UseUnique(input);
1101 } 1103 }
1102 } 1104 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 MachineOperatorBuilder::Flags 1176 MachineOperatorBuilder::Flags
1175 InstructionSelector::SupportedMachineOperatorFlags() { 1177 InstructionSelector::SupportedMachineOperatorFlags() {
1176 return MachineOperatorBuilder::Flag::kNoFlags; 1178 return MachineOperatorBuilder::Flag::kNoFlags;
1177 } 1179 }
1178 1180
1179 #endif // !V8_TURBOFAN_BACKEND 1181 #endif // !V8_TURBOFAN_BACKEND
1180 1182
1181 } // namespace compiler 1183 } // namespace compiler
1182 } // namespace internal 1184 } // namespace internal
1183 } // namespace v8 1185 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/instruction-selector.h ('k') | src/compiler/instruction-selector-impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698