24 auto c2_iterator = input_types.
begin();
30 merged_types.
Push(merged_type);
40 std::stringstream error;
41 error <<
"incompatible types at branch:\n";
44 std::optional<const Type*> left;
45 std::optional<const Type*> right;
46 if (
static_cast<size_t>(
i) < input_types.
Size()) {
52 if (left && right && *left == *right) {
53 error << **left <<
"\n";
58 error <<
"/*missing*/";
64 error <<
"/*missing*/";
74 DCHECK(block->instructions().empty());
75 DCHECK(block->HasInputTypes());
82 if (block->HasInputTypes()) {
83 DropTo(block->InputTypes().AboveTop());
89 DCHECK(block->HasInputTypes());
92 StackRange{block->InputTypes().AboveTop() - preserved_slots,
96 return preserved_slot_range;
106 if (range.Size() == 0)
return;
115 std::optional<const Type*> type) {
116 std::vector<const Type*> lowered_types;
119 DCHECK_EQ(lowered_types.size(), range.Size());
121 for (
size_t i = 0;
i < range.Size(); ++
i) {
124 type ? lowered_types[
i] : std::optional<const Type*>{}});
130 std::optional<const Type*> type) {
134 std::vector<const Type*> lowered_types;
139 for (intptr_t
i = origin.
Size() - 1;
i >= 0; --
i) {
142 type ? lowered_types[
i] : std::optional<const Type*>{}});
152 std::move(message)});
168 std::vector<Block*> successors;
169 for (
const auto& instruction : block->instructions()) {
170 instruction->AppendSuccessorBlocks(&successors);
172 for (
Block* successor : successors) {
174 ++
count[successor->id()];
186 if (predecessor_count[block->id()] == 0)
continue;
188 while (!block->instructions().empty()) {
189 const auto& instruction = block->instructions().back();
195 if (predecessor_count[
destination->id()] != 1)
break;
198 block->instructions().pop_back();
199 block->instructions().insert(block->instructions().end(),
209 [&](
Block* b) {
return predecessor_count[b->
id()] == 0; });
228 for (
const auto& instruction : block->instructions()) {
229 instruction.RecomputeDefinitionLocations(&definitions, &worklist);
234 DCHECK_IMPLIES(!block->IsDead(), block->InputDefinitions().Size() ==
235 block->InputTypes().Size());
const Stack< const Type * > & InputTypes() const
void MergeInputDefinitions(const Stack< DefinitionLocation > &input_definitions, Worklist< Block * > *worklist)
std::optional< Stack< const Type * > > input_types_
void SetInputTypes(const Stack< const Type * > &input_types)
StackRange Peek(StackRange range, std::optional< const Type * > type)
StackRange TopRange(size_t slot_count) const
void AssertionFailure(std::string message)
Stack< const Type * > current_stack_
const Stack< const Type * > & CurrentStack() const
void Branch(Block *if_true, Block *if_false)
void DropTo(BottomOffset new_level)
void ComputeInputDefinitions()
void Poke(StackRange destination, StackRange origin, std::optional< const Type * > type)
void Print(std::string s)
void Emit(Instruction instruction)
void DeleteRange(StackRange range)
std::size_t ParameterCount() const
size_t NumberOfBlockIds() const
void UnplaceBlockIf(UnaryPredicate &&predicate)
void PlaceBlock(Block *block)
const std::vector< Block * > & blocks() const
std::optional< Block * > end() const
static DefinitionLocation Parameter(std::size_t index)
BottomOffset begin() const
const T & Peek(BottomOffset from_bottom) const
static const Type * GetUnionType(UnionType type)
virtual bool IsSubtypeOf(const Type *supertype) const
InstructionOperand destination
void ReportError(Args &&... args)
TypeVector LowerType(const Type *type)
std::vector< std::size_t > CountBlockPredecessors(const ControlFlowGraph &cfg)
#define DCHECK_LE(v1, v2)
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK_GE(v1, v2)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)
#define DCHECK_GT(v1, v2)