5 #include "src/torque/cfg.h" 7 #include "src/torque/type-oracle.h" 13 void Block::SetInputTypes(
const Stack<const Type*>& input_types) {
15 input_types_ = input_types;
17 }
else if (*input_types_ == input_types) {
21 DCHECK_EQ(input_types.Size(), input_types_->Size());
22 Stack<const Type*> merged_types;
24 auto c2_iterator = input_types.begin();
25 for (
const Type* c1 : *input_types_) {
26 const Type* merged_type = TypeOracle::GetUnionType(c1, *c2_iterator++);
27 if (!merged_type->IsSubtypeOf(c1)) {
30 merged_types.Push(merged_type);
32 if (merged_types.Size() == input_types_->Size()) {
34 input_types_ = merged_types;
40 std::stringstream error;
41 error <<
"incompatible types at branch:\n";
42 for (intptr_t
i = std::max(input_types_->Size(), input_types.Size()) - 1;
44 base::Optional<const Type*> left;
45 base::Optional<const Type*> right;
46 if (static_cast<size_t>(
i) < input_types.Size()) {
47 left = input_types.Peek(BottomOffset{
static_cast<size_t>(
i)});
49 if (static_cast<size_t>(
i) < input_types_->Size()) {
50 right = input_types_->Peek(BottomOffset{
static_cast<size_t>(
i)});
52 if (left && right && *left == *right) {
53 error << **left <<
"\n";
58 error <<
"/*missing*/";
64 error <<
"/*missing*/";
69 ReportError(error.str());
72 void CfgAssembler::Bind(Block* block) {
73 DCHECK(current_block_->IsComplete());
74 DCHECK(block->instructions().empty());
75 DCHECK(block->HasInputTypes());
76 current_block_ = block;
77 current_stack_ = block->InputTypes();
78 cfg_.PlaceBlock(block);
81 void CfgAssembler::Goto(Block* block) {
82 if (block->HasInputTypes()) {
83 DropTo(block->InputTypes().AboveTop());
85 Emit(GotoInstruction{block});
88 StackRange CfgAssembler::Goto(Block* block,
size_t preserved_slots) {
89 DCHECK(block->HasInputTypes());
90 DCHECK_GE(CurrentStack().Size(), block->InputTypes().Size());
91 Emit(DeleteRangeInstruction{
92 StackRange{block->InputTypes().AboveTop() - preserved_slots,
93 CurrentStack().AboveTop() - preserved_slots}});
94 StackRange preserved_slot_range = TopRange(preserved_slots);
95 Emit(GotoInstruction{block});
96 return preserved_slot_range;
99 void CfgAssembler::Branch(Block* if_true, Block* if_false) {
100 Emit(BranchInstruction{if_true, if_false});
104 void CfgAssembler::DeleteRange(StackRange range) {
105 DCHECK_LE(range.end(), current_stack_.AboveTop());
106 if (range.Size() == 0)
return;
107 Emit(DeleteRangeInstruction{range});
110 void CfgAssembler::DropTo(BottomOffset new_level) {
111 DeleteRange(StackRange{new_level, CurrentStack().AboveTop()});
114 StackRange CfgAssembler::Peek(StackRange range,
115 base::Optional<const Type*> type) {
116 std::vector<const Type*> lowered_types;
118 lowered_types = LowerType(*type);
119 DCHECK_EQ(lowered_types.size(), range.Size());
121 for (
size_t i = 0;
i < range.Size(); ++
i) {
122 Emit(PeekInstruction{
124 type ? lowered_types[
i] : base::Optional<const Type*>{}});
126 return TopRange(range.Size());
129 void CfgAssembler::Poke(StackRange destination, StackRange origin,
130 base::Optional<const Type*> type) {
131 DCHECK_EQ(destination.Size(), origin.Size());
132 DCHECK_LE(destination.end(), origin.begin());
133 DCHECK_EQ(origin.end(), CurrentStack().AboveTop());
134 std::vector<const Type*> lowered_types;
136 lowered_types = LowerType(*type);
137 DCHECK_EQ(lowered_types.size(), origin.Size());
139 for (intptr_t
i = origin.Size() - 1;
i >= 0; --
i) {
140 Emit(PokeInstruction{
141 destination.begin() +
i,
142 type ? lowered_types[
i] : base::Optional<const Type*>{}});
146 void CfgAssembler::Print(std::string s) {
147 Emit(PrintConstantStringInstruction{std::move(s)});
150 void CfgAssembler::AssertionFailure(std::string message) {
151 Emit(AbortInstruction{AbortInstruction::Kind::kAssertionFailure,
152 std::move(message)});
155 void CfgAssembler::Unreachable() {
156 Emit(AbortInstruction{AbortInstruction::Kind::kUnreachable});
159 void CfgAssembler::DebugBreak() {
160 Emit(AbortInstruction{AbortInstruction::Kind::kDebugBreak});