v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
instructions.cc
Go to the documentation of this file.
1// Copyright 2018 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
6
7#include <optional>
8
9#include "src/torque/cfg.h"
11
12namespace v8::internal::torque {
13
14#define TORQUE_INSTRUCTION_BOILERPLATE_DEFINITIONS(Name) \
15 const InstructionKind Name::kKind = InstructionKind::k##Name; \
16 std::unique_ptr<InstructionBase> Name::Clone() const { \
17 return std::unique_ptr<InstructionBase>(new Name(*this)); \
18 } \
19 void Name::Assign(const InstructionBase& other) { \
20 *this = static_cast<const Name&>(other); \
21 }
23#undef TORQUE_INSTRUCTION_BOILERPLATE_DEFINITIONS
24
25namespace {
26void ExpectType(const Type* expected, const Type* actual) {
27 if (expected != actual) {
28 ReportError("expected type ", *expected, " but found ", *actual);
29 }
30}
31void ExpectSubtype(const Type* subtype, const Type* supertype) {
32 if (!subtype->IsSubtypeOf(supertype)) {
33 ReportError("type ", *subtype, " is not a subtype of ", *supertype);
34 }
35}
36} // namespace
37
38void PeekInstruction::TypeInstruction(Stack<const Type*>* stack,
39 ControlFlowGraph* cfg) const {
40 const Type* type = stack->Peek(slot);
41 if (widened_type) {
42 if (type->IsTopType()) {
43 const TopType* top_type = TopType::cast(type);
44 ReportError("use of " + top_type->reason());
45 }
46 ExpectSubtype(type, *widened_type);
47 type = *widened_type;
48 }
49 stack->Push(type);
50}
51
53 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
54 locations->Push(locations->Peek(slot));
55}
56
57void PokeInstruction::TypeInstruction(Stack<const Type*>* stack,
58 ControlFlowGraph* cfg) const {
59 const Type* type = stack->Top();
60 if (widened_type) {
61 ExpectSubtype(type, *widened_type);
62 type = *widened_type;
63 }
64 stack->Poke(slot, type);
65 stack->Pop();
66}
67
69 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
70 locations->Poke(slot, locations->Pop());
71}
72
73void DeleteRangeInstruction::TypeInstruction(Stack<const Type*>* stack,
74 ControlFlowGraph* cfg) const {
75 stack->DeleteRange(range);
76}
77
79 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
80 locations->DeleteRange(range);
81}
82
84 Stack<const Type*>* stack, ControlFlowGraph* cfg) const {
85 stack->Push(type);
86}
87
89 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
90 locations->Push(GetValueDefinition());
91}
92
96
98 Stack<const Type*>* stack, ControlFlowGraph* cfg) const {
99 stack->Push(type);
100}
101
103 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
104 locations->Push(GetValueDefinition());
105}
106
110
112 Stack<const Type*>* stack, ControlFlowGraph* cfg) const {
113 stack->PushMany(LowerType(constant->type()));
114}
115
117 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
118 for (std::size_t i = 0; i < GetValueDefinitionCount(); ++i) {
119 locations->Push(GetValueDefinition(i));
120 }
121}
122
124 return LowerType(constant->type()).size();
125}
126
132
133std::ostream& operator<<(std::ostream& os,
134 const NamespaceConstantInstruction& instruction) {
135 return os << "NamespaceConstant " << instruction.constant->external_name();
136}
137
139 Stack<const Type*>* stack) const {
140 auto current = stack->begin();
141 while (current != stack->end()) {
142 if ((*current)->IsTransient()) {
143 std::stringstream stream;
144 stream << "type " << **current
145 << " is made invalid by transitioning callable invocation at "
147 *current = TypeOracle::GetTopType(stream.str(), *current);
148 }
149 ++current;
150 }
151}
152
154 ControlFlowGraph* cfg) const {
155 std::vector<const Type*> parameter_types =
156 LowerParameterTypes(intrinsic->signature().parameter_types);
157 for (intptr_t i = parameter_types.size() - 1; i >= 0; --i) {
158 const Type* arg_type = stack->Pop();
159 const Type* parameter_type = parameter_types.back();
160 parameter_types.pop_back();
161 if (arg_type != parameter_type) {
162 ReportError("parameter ", i, ": expected type ", *parameter_type,
163 " but found type ", *arg_type);
164 }
165 }
166 if (intrinsic->IsTransitioning()) {
168 }
169 stack->PushMany(LowerType(intrinsic->signature().return_type));
170}
171
173 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
174 auto parameter_types =
175 LowerParameterTypes(intrinsic->signature().parameter_types);
176 locations->PopMany(parameter_types.size());
177 for (std::size_t i = 0; i < GetValueDefinitionCount(); ++i) {
178 locations->Push(DefinitionLocation::Instruction(this, i));
179 }
180}
181
183 return LowerType(intrinsic->signature().return_type).size();
184}
185
191
192std::ostream& operator<<(std::ostream& os,
193 const CallIntrinsicInstruction& instruction) {
194 os << "CallIntrinsic " << instruction.intrinsic->ReadableName();
195 if (!instruction.specialization_types.empty()) {
196 os << "<";
198 os, instruction.specialization_types,
199 [](const Type* type) -> const Type& { return *type; });
200 os << ">";
201 }
202 os << "(";
203 PrintCommaSeparatedList(os, instruction.constexpr_arguments);
204 os << ")";
205 return os;
206}
207
208void CallCsaMacroInstruction::TypeInstruction(Stack<const Type*>* stack,
209 ControlFlowGraph* cfg) const {
210 std::vector<const Type*> parameter_types =
211 LowerParameterTypes(macro->signature().parameter_types);
212 for (intptr_t i = parameter_types.size() - 1; i >= 0; --i) {
213 const Type* arg_type = stack->Pop();
214 const Type* parameter_type = parameter_types.back();
215 parameter_types.pop_back();
216 if (arg_type != parameter_type) {
217 ReportError("parameter ", i, ": expected type ", *parameter_type,
218 " but found type ", *arg_type);
219 }
220 }
221
222 if (macro->IsTransitioning()) {
224 }
225
226 if (catch_block) {
227 Stack<const Type*> catch_stack = *stack;
228 catch_stack.Push(TypeOracle::GetJSAnyType());
229 (*catch_block)->SetInputTypes(catch_stack);
230 }
231
232 stack->PushMany(LowerType(macro->signature().return_type));
233}
234
236 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
237 auto parameter_types =
238 LowerParameterTypes(macro->signature().parameter_types);
239 locations->PopMany(parameter_types.size());
240
241 if (catch_block) {
242 locations->Push(*GetExceptionObjectDefinition());
243 (*catch_block)->MergeInputDefinitions(*locations, worklist);
244 locations->Pop();
245 }
246
247 for (std::size_t i = 0; i < GetValueDefinitionCount(); ++i) {
248 locations->Push(GetValueDefinition(i));
249 }
250}
251
252std::optional<DefinitionLocation>
257
259 return LowerType(macro->signature().return_type).size();
260}
261
267
268std::ostream& operator<<(std::ostream& os,
269 const CallCsaMacroInstruction& instruction) {
270 os << "CallCsaMacro " << instruction.macro->ReadableName();
271 os << "(";
272 PrintCommaSeparatedList(os, instruction.constexpr_arguments);
273 os << ")";
274 if (instruction.catch_block) {
275 os << ", catch block " << (*instruction.catch_block)->id();
276 }
277 return os;
278}
279
281 Stack<const Type*>* stack, ControlFlowGraph* cfg) const {
282 std::vector<const Type*> parameter_types =
283 LowerParameterTypes(macro->signature().parameter_types);
284 for (intptr_t i = parameter_types.size() - 1; i >= 0; --i) {
285 const Type* arg_type = stack->Pop();
286 const Type* parameter_type = parameter_types.back();
287 parameter_types.pop_back();
288 if (arg_type != parameter_type) {
289 ReportError("parameter ", i, ": expected type ", *parameter_type,
290 " but found type ", *arg_type);
291 }
292 }
293
294 if (label_blocks.size() != macro->signature().labels.size()) {
295 ReportError("wrong number of labels");
296 }
297 for (size_t i = 0; i < label_blocks.size(); ++i) {
298 Stack<const Type*> continuation_stack = *stack;
299 continuation_stack.PushMany(
300 LowerParameterTypes(macro->signature().labels[i].types));
301 label_blocks[i]->SetInputTypes(std::move(continuation_stack));
302 }
303
304 if (macro->IsTransitioning()) {
306 }
307
308 if (catch_block) {
309 Stack<const Type*> catch_stack = *stack;
310 catch_stack.Push(TypeOracle::GetJSAnyType());
311 (*catch_block)->SetInputTypes(catch_stack);
312 }
313
314 if (macro->signature().return_type != TypeOracle::GetNeverType()) {
315 Stack<const Type*> return_stack = *stack;
316 return_stack.PushMany(LowerType(macro->signature().return_type));
317 if (return_continuation == std::nullopt) {
318 ReportError("missing return continuation.");
319 }
320 (*return_continuation)->SetInputTypes(return_stack);
321 } else {
322 if (return_continuation != std::nullopt) {
323 ReportError("unreachable return continuation.");
324 }
325 }
326}
327
329 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
330 auto parameter_types =
331 LowerParameterTypes(macro->signature().parameter_types);
332 locations->PopMany(parameter_types.size());
333
334 for (std::size_t label_index = 0; label_index < label_blocks.size();
335 ++label_index) {
336 const std::size_t count = GetLabelValueDefinitionCount(label_index);
337 for (std::size_t i = 0; i < count; ++i) {
338 locations->Push(GetLabelValueDefinition(label_index, i));
339 }
340 label_blocks[label_index]->MergeInputDefinitions(*locations, worklist);
341 locations->PopMany(count);
342 }
343
344 if (catch_block) {
345 locations->Push(*GetExceptionObjectDefinition());
346 (*catch_block)->MergeInputDefinitions(*locations, worklist);
347 locations->Pop();
348 }
349
350 if (macro->signature().return_type != TypeOracle::GetNeverType()) {
352 const std::size_t count = GetValueDefinitionCount();
353 for (std::size_t i = 0; i < count; ++i) {
354 locations->Push(GetValueDefinition(i));
355 }
356 (*return_continuation)->MergeInputDefinitions(*locations, worklist);
357 locations->PopMany(count);
358 }
359 }
360}
361
363 return label_blocks.size();
364}
365
367 std::size_t label) const {
369 return LowerParameterTypes(macro->signature().labels[label].types).size();
370}
371
373 std::size_t label, std::size_t index) const {
375 std::size_t offset = GetValueDefinitionCount() + (catch_block ? 1 : 0);
376 for (std::size_t label_index = 0; label_index < label; ++label_index) {
377 offset += GetLabelValueDefinitionCount(label_index);
378 }
379 return DefinitionLocation::Instruction(this, offset + index);
380}
381
383 if (macro->signature().return_type == TypeOracle::GetNeverType()) return 0;
384 if (!return_continuation) return 0;
385 return LowerType(macro->signature().return_type).size();
386}
387
393
394std::optional<DefinitionLocation>
399
400std::ostream& operator<<(std::ostream& os,
401 const CallCsaMacroAndBranchInstruction& instruction) {
402 os << "CallCsaMacroAndBranch " << instruction.macro->ReadableName();
403 os << "(";
404 PrintCommaSeparatedList(os, instruction.constexpr_arguments);
405 os << ")";
406 if (instruction.return_continuation) {
407 os << ", return continuation " << (*instruction.return_continuation)->id();
408 }
409 if (!instruction.label_blocks.empty()) {
410 os << ", label blocks ";
411 PrintCommaSeparatedList(os, instruction.label_blocks,
412 [](Block* block) { return block->id(); });
413 }
414 if (instruction.catch_block) {
415 os << ", catch block " << (*instruction.catch_block)->id();
416 }
417 return os;
418}
419
420void CallBuiltinInstruction::TypeInstruction(Stack<const Type*>* stack,
421 ControlFlowGraph* cfg) const {
422 std::vector<const Type*> argument_types = stack->PopMany(argc);
423 if (argument_types !=
424 LowerParameterTypes(builtin->signature().parameter_types)) {
425 ReportError("wrong argument types");
426 }
427 if (builtin->IsTransitioning()) {
429 }
430
431 if (catch_block) {
432 Stack<const Type*> catch_stack = *stack;
433 catch_stack.Push(TypeOracle::GetJSAnyType());
434 (*catch_block)->SetInputTypes(catch_stack);
435 }
436
437 stack->PushMany(LowerType(builtin->signature().return_type));
438}
439
441 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
442 locations->PopMany(argc);
443
444 if (catch_block) {
445 locations->Push(*GetExceptionObjectDefinition());
446 (*catch_block)->MergeInputDefinitions(*locations, worklist);
447 locations->Pop();
448 }
449
450 for (std::size_t i = 0; i < GetValueDefinitionCount(); ++i) {
451 locations->Push(GetValueDefinition(i));
452 }
453}
454
456 return LowerType(builtin->signature().return_type).size();
457}
458
464
465std::optional<DefinitionLocation>
470
472 Stack<const Type*>* stack, ControlFlowGraph* cfg) const {
473 std::vector<const Type*> argument_types = stack->PopMany(argc);
474 const BuiltinPointerType* f = BuiltinPointerType::DynamicCast(stack->Pop());
475 if (!f) ReportError("expected function pointer type");
476 if (argument_types != LowerParameterTypes(f->parameter_types())) {
477 ReportError("wrong argument types");
478 }
479 DCHECK_EQ(type, f);
480 // TODO(turbofan): Only invalidate transient types if the function pointer
481 // type is transitioning.
483 stack->PushMany(LowerType(f->return_type()));
484}
485
487 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
488 locations->PopMany(argc + 1);
489 for (std::size_t i = 0; i < GetValueDefinitionCount(); ++i) {
490 locations->Push(GetValueDefinition(i));
491 }
492}
493
495 return LowerType(type->return_type()).size();
496}
497
503
504std::ostream& operator<<(std::ostream& os,
505 const CallBuiltinInstruction& instruction) {
506 os << "CallBuiltin " << instruction.builtin->ReadableName()
507 << ", argc: " << instruction.argc;
508 if (instruction.is_tailcall) {
509 os << ", is_tailcall";
510 }
511 if (instruction.catch_block) {
512 os << ", catch block " << (*instruction.catch_block)->id();
513 }
514 return os;
515}
516
517void CallRuntimeInstruction::TypeInstruction(Stack<const Type*>* stack,
518 ControlFlowGraph* cfg) const {
519 std::vector<const Type*> argument_types = stack->PopMany(argc);
520 if (argument_types !=
522 argc)) {
523 ReportError("wrong argument types");
524 }
527 }
528
529 if (catch_block) {
530 Stack<const Type*> catch_stack = *stack;
531 catch_stack.Push(TypeOracle::GetJSAnyType());
532 (*catch_block)->SetInputTypes(catch_stack);
533 }
534
535 const Type* return_type = runtime_function->signature().return_type;
536 if (return_type != TypeOracle::GetNeverType()) {
537 stack->PushMany(LowerType(return_type));
538 }
539}
540
542 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
543 locations->PopMany(argc);
544
545 if (catch_block) {
546 locations->Push(*GetExceptionObjectDefinition());
547 (*catch_block)->MergeInputDefinitions(*locations, worklist);
548 locations->Pop();
549 }
550
551 const Type* return_type = runtime_function->signature().return_type;
552 if (return_type != TypeOracle::GetNeverType()) {
553 for (std::size_t i = 0; i < GetValueDefinitionCount(); ++i) {
554 locations->Push(GetValueDefinition(i));
555 }
556 }
557}
558
560 const Type* return_type = runtime_function->signature().return_type;
561 if (return_type == TypeOracle::GetNeverType()) return 0;
562 return LowerType(return_type).size();
563}
564
570
571std::optional<DefinitionLocation>
576
577std::ostream& operator<<(std::ostream& os,
578 const CallRuntimeInstruction& instruction) {
579 os << "CallRuntime " << instruction.runtime_function->ReadableName()
580 << ", argc: " << instruction.argc;
581 if (instruction.is_tailcall) {
582 os << ", is_tailcall";
583 }
584 if (instruction.catch_block) {
585 os << ", catch block " << (*instruction.catch_block)->id();
586 }
587 return os;
588}
589
590void BranchInstruction::TypeInstruction(Stack<const Type*>* stack,
591 ControlFlowGraph* cfg) const {
592 const Type* condition_type = stack->Pop();
593 if (condition_type != TypeOracle::GetBoolType()) {
594 ReportError("condition has to have type bool");
595 }
596 if_true->SetInputTypes(*stack);
597 if_false->SetInputTypes(*stack);
598}
599
601 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
602 locations->Pop();
603 if_true->MergeInputDefinitions(*locations, worklist);
604 if_false->MergeInputDefinitions(*locations, worklist);
605}
606
607std::ostream& operator<<(std::ostream& os,
608 const BranchInstruction& instruction) {
609 return os << "Branch true: " << instruction.if_true->id()
610 << ", false: " << instruction.if_false->id();
611}
612
613void ConstexprBranchInstruction::TypeInstruction(Stack<const Type*>* stack,
614 ControlFlowGraph* cfg) const {
615 if_true->SetInputTypes(*stack);
616 if_false->SetInputTypes(*stack);
617}
618
620 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
621 if_true->MergeInputDefinitions(*locations, worklist);
622 if_false->MergeInputDefinitions(*locations, worklist);
623}
624
625std::ostream& operator<<(std::ostream& os,
626 const ConstexprBranchInstruction& instruction) {
627 return os << "ConstexprBranch " << instruction.condition
628 << ", true: " << instruction.if_true->id()
629 << ", false: " << instruction.if_false->id();
630}
631
632void GotoInstruction::TypeInstruction(Stack<const Type*>* stack,
633 ControlFlowGraph* cfg) const {
634 destination->SetInputTypes(*stack);
635}
636
638 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
639 destination->MergeInputDefinitions(*locations, worklist);
640}
641
642std::ostream& operator<<(std::ostream& os, const GotoInstruction& instruction) {
643 return os << "Goto " << instruction.destination->id();
644}
645
646void GotoExternalInstruction::TypeInstruction(Stack<const Type*>* stack,
647 ControlFlowGraph* cfg) const {
648 if (variable_names.size() != stack->Size()) {
649 ReportError("goto external label with wrong parameter count.");
650 }
651}
652
654 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {}
655
656void ReturnInstruction::TypeInstruction(Stack<const Type*>* stack,
657 ControlFlowGraph* cfg) const {
658 cfg->SetReturnType(stack->PopMany(count));
659}
660
662 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
663 locations->PopMany(count);
664}
665
666void PrintErrorInstruction::TypeInstruction(Stack<const Type*>* stack,
667 ControlFlowGraph* cfg) const {}
668
670 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {}
671
672void AbortInstruction::TypeInstruction(Stack<const Type*>* stack,
673 ControlFlowGraph* cfg) const {}
674
676 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {}
677
678void UnsafeCastInstruction::TypeInstruction(Stack<const Type*>* stack,
679 ControlFlowGraph* cfg) const {
680 stack->Poke(stack->AboveTop() - 1, destination_type);
681}
682
684 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
685 locations->Poke(locations->AboveTop() - 1, GetValueDefinition());
686}
687
691
693 ControlFlowGraph* cfg) const {
694 ExpectType(TypeOracle::GetIntPtrType(), stack->Pop());
695 ExpectSubtype(stack->Pop(), TypeOracle::GetUnionType(
698 DCHECK_EQ(std::vector<const Type*>{type}, LowerType(type));
699 stack->Push(type);
700}
701
703 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
704 locations->Pop();
705 locations->Pop();
706 locations->Push(GetValueDefinition());
707}
708
712
714 ControlFlowGraph* cfg) const {
715 ExpectSubtype(stack->Pop(), type);
716 ExpectType(TypeOracle::GetIntPtrType(), stack->Pop());
717 ExpectSubtype(stack->Pop(), TypeOracle::GetUnionType(
720}
721
723 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
724 locations->Pop();
725 locations->Pop();
726 locations->Pop();
727}
728
729void LoadBitFieldInstruction::TypeInstruction(Stack<const Type*>* stack,
730 ControlFlowGraph* cfg) const {
731 ExpectType(bit_field_struct_type, stack->Pop());
732 stack->Push(bit_field.name_and_type.type);
733}
734
736 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
737 locations->Pop();
738 locations->Push(GetValueDefinition());
739}
740
744
746 ControlFlowGraph* cfg) const {
747 ExpectSubtype(bit_field.name_and_type.type, stack->Pop());
748 ExpectType(bit_field_struct_type, stack->Pop());
749 stack->Push(bit_field_struct_type);
750}
751
753 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
754 locations->Pop();
755 locations->Pop();
756 locations->Push(GetValueDefinition());
757}
758
762
764 ControlFlowGraph* cfg) const {
765 std::vector<const Type*> parameter_types =
766 LowerParameterTypes(macro->signature().parameter_types);
767 for (intptr_t i = parameter_types.size() - 1; i >= 0; --i) {
768 const Type* arg_type = stack->Pop();
769 const Type* parameter_type = parameter_types.back();
770 parameter_types.pop_back();
771 if (arg_type != parameter_type) {
772 ReportError("parameter ", i, ": expected type ", *parameter_type,
773 " but found type ", *arg_type);
774 }
775 }
776
777 stack->Push(result_type);
778}
779
781 Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
782 auto parameter_types =
783 LowerParameterTypes(macro->signature().parameter_types);
784 locations->PopMany(parameter_types.size());
785
786 locations->Push(GetValueDefinition());
787}
788
792
793std::ostream& operator<<(std::ostream& os,
794 const MakeLazyNodeInstruction& instruction) {
795 os << "MakeLazyNode " << instruction.macro->ReadableName() << ", "
796 << *instruction.result_type;
797 for (const std::string& arg : instruction.constexpr_arguments) {
798 os << ", " << arg;
799 }
800 return os;
801}
802
807
808} // namespace v8::internal::torque
void MergeInputDefinitions(const Stack< DefinitionLocation > &input_definitions, Worklist< Block * > *worklist)
Definition cfg.h:55
void SetInputTypes(const Stack< const Type * > &input_types)
Definition cfg.cc:13
const TypeVector & parameter_types() const
Definition types.h:345
const Type * return_type() const
Definition types.h:346
const Signature & signature() const
Definition declarable.h:306
static DefinitionLocation Instruction(const InstructionBase *instruction, std::size_t index=0)
static const Type * GetUnionType(UnionType type)
static const Type * GetHeapObjectType()
static const Type * GetTaggedZeroPatternType()
static const TopType * GetTopType(std::string reason, const Type *source_type)
static const Type * GetIntPtrType()
static const Type * GetBoolType()
static const Type * GetJSAnyType()
static const Type * GetNeverType()
uint32_t count
LineAndColumn current
Label label
int32_t offset
#define TORQUE_INSTRUCTION_BOILERPLATE_DEFINITIONS(Name)
#define TORQUE_INSTRUCTION_LIST(V)
ZoneStack< RpoNumber > & stack
std::ostream & operator<<(std::ostream &os, Identifier *id)
Definition ast.h:263
void ReportError(Args &&... args)
Definition utils.h:96
std::string PositionAsString(SourcePosition pos)
TypeVector LowerType(const Type *type)
Definition types.cc:1210
void PrintCommaSeparatedList(std::ostream &os, const T &list, C &&transform)
Definition utils.h:163
TypeVector LowerParameterTypes(const TypeVector &parameters)
Definition types.cc:1218
#define DCHECK_LT(v1, v2)
Definition logging.h:489
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
std::optional< DefinitionLocation > GetExceptionObjectDefinition() const
DefinitionLocation GetValueDefinition(std::size_t index) const
DefinitionLocation GetValueDefinition(std::size_t index) const
DefinitionLocation GetValueDefinition(std::size_t index) const
std::optional< DefinitionLocation > GetExceptionObjectDefinition() const
DefinitionLocation GetLabelValueDefinition(std::size_t label, std::size_t index) const
std::size_t GetLabelValueDefinitionCount(std::size_t label) const
std::optional< DefinitionLocation > GetExceptionObjectDefinition() const
DefinitionLocation GetValueDefinition(std::size_t index) const
DefinitionLocation GetValueDefinition(std::size_t index) const
DefinitionLocation GetValueDefinition(std::size_t index) const
std::optional< DefinitionLocation > GetExceptionObjectDefinition() const
virtual void RecomputeDefinitionLocations(Stack< DefinitionLocation > *locations, Worklist< Block * > *worklist) const =0
void InvalidateTransientTypes(Stack< const Type * > *stack) const
virtual void TypeInstruction(Stack< const Type * > *stack, ControlFlowGraph *cfg) const =0
DefinitionLocation GetValueDefinition() const
DefinitionLocation GetValueDefinition() const
DefinitionLocation GetValueDefinition(std::size_t index) const
std::optional< const Type * > widened_type
std::optional< const Type * > widened_type
DefinitionLocation GetValueDefinition() const