}
static bool DominatesAllBackEdges(HBasicBlock* block, HLoopInformation* loop_info) {
- for (size_t i = 0, e = loop_info->GetBackEdges().Size(); i < e; ++i) {
- HBasicBlock* back_edge = loop_info->GetBackEdges().Get(i);
+ for (HBasicBlock* back_edge : loop_info->GetBackEdges()) {
if (!block->Dominates(back_edge)) {
return false;
}
BCEVisitor(HGraph* graph, HInductionVarAnalysis* induction_analysis)
: HGraphVisitor(graph),
- maps_(graph->GetBlocks().Size()),
+ maps_(graph->GetBlocks().size()),
need_to_revisit_block_(false),
- initial_block_size_(graph->GetBlocks().Size()),
+ initial_block_size_(graph->GetBlocks().size()),
induction_range_(induction_analysis) {}
void VisitBasicBlock(HBasicBlock* block) OVERRIDE {
bool need_to_revisit_block_;
// Initial number of blocks.
- int32_t initial_block_size_;
+ uint32_t initial_block_size_;
// Range analysis based on induction variables.
InductionVarRange induction_range_;
// Bit vector stores information on which blocks contain throwing instructions.
// Must be expandable because catch blocks may be split into two.
- ArenaBitVector can_block_throw(arena_, graph_->GetBlocks().Size(), /* expandable */ true);
+ ArenaBitVector can_block_throw(arena_, graph_->GetBlocks().size(), /* expandable */ true);
// Scan blocks and mark those which contain throwing instructions.
- for (size_t block_id = 0, e = graph_->GetBlocks().Size(); block_id < e; ++block_id) {
- HBasicBlock* block = graph_->GetBlocks().Get(block_id);
+ for (HBasicBlock* block : graph_->GetBlocks()) {
bool can_throw = false;
for (HInstructionIterator insn(block->GetInstructions()); !insn.Done(); insn.Advance()) {
if (insn.Current()->CanThrow()) {
// (c) link the new blocks to corresponding exception handlers.
// We cannot iterate only over blocks in `branch_targets_` because switch-case
// blocks share the same dex_pc.
- for (size_t block_id = 0, e = graph_->GetBlocks().Size(); block_id < e; ++block_id) {
- HBasicBlock* try_block = graph_->GetBlocks().Get(block_id);
-
+ for (HBasicBlock* try_block : graph_->GetBlocks()) {
// TryBoundary blocks are added at the end of the list and not iterated over.
DCHECK(!try_block->IsSingleTryBoundary());
}
bool HGraphBuilder::BuildGraph(const DexFile::CodeItem& code_item) {
- DCHECK(graph_->GetBlocks().IsEmpty());
+ DCHECK(graph_->GetBlocks().empty());
const uint16_t* code_ptr = code_item.insns_;
const uint16_t* code_end = code_item.insns_ + code_item.insns_size_in_code_units_;
}
bool CodeGenerator::GoesToNextBlock(HBasicBlock* current, HBasicBlock* next) const {
- DCHECK_EQ(block_order_->Get(current_block_index_), current);
+ DCHECK_LT(current_block_index_, block_order_->size());
+ DCHECK_EQ((*block_order_)[current_block_index_], current);
return GetNextBlockToEmit() == FirstNonEmptyBlock(next);
}
HBasicBlock* CodeGenerator::GetNextBlockToEmit() const {
- for (size_t i = current_block_index_ + 1; i < block_order_->Size(); ++i) {
- HBasicBlock* block = block_order_->Get(i);
+ for (size_t i = current_block_index_ + 1; i < block_order_->size(); ++i) {
+ HBasicBlock* block = (*block_order_)[i];
if (!block->IsSingleJump()) {
return block;
}
disasm_info_->SetFrameEntryInterval(frame_start, GetAssembler()->CodeSize());
}
- for (size_t e = block_order_->Size(); current_block_index_ < e; ++current_block_index_) {
- HBasicBlock* block = block_order_->Get(current_block_index_);
+ for (size_t e = block_order_->size(); current_block_index_ < e; ++current_block_index_) {
+ HBasicBlock* block = (*block_order_)[current_block_index_];
// Don't generate code for an empty block. Its predecessors will branch to its successor
// directly. Also, the label of that block will not be emitted, so this helps catch
// errors where we reference that label.
size_t maximum_number_of_live_core_registers,
size_t maximum_number_of_live_fp_registers,
size_t number_of_out_slots,
- const GrowableArray<HBasicBlock*>& block_order) {
+ const ArenaVector<HBasicBlock*>& block_order) {
block_order_ = &block_order;
- DCHECK(block_order_->Get(0) == GetGraph()->GetEntryBlock());
+ DCHECK(!block_order.empty());
+ DCHECK(block_order[0] == GetGraph()->GetEntryBlock());
ComputeSpillMask();
first_register_slot_in_slow_path_ = (number_of_out_slots + number_of_spill_slots) * kVRegSize;
}
// Walk over the blocks and find which ones correspond to catch block entries.
- for (size_t i = 0; i < graph_->GetBlocks().Size(); ++i) {
- HBasicBlock* block = graph_->GetBlocks().Get(i);
+ for (HBasicBlock* block : graph_->GetBlocks()) {
if (block->IsCatchBlock()) {
intptr_t native_pc = GetAddressOf(block);
++dex2pc_entries;
pc2dex_dalvik_offset = stack_map_entry.dex_pc;
}
- for (size_t i = 0; i < graph_->GetBlocks().Size(); ++i) {
- HBasicBlock* block = graph_->GetBlocks().Get(i);
+ for (HBasicBlock* block : graph_->GetBlocks()) {
if (block->IsCatchBlock()) {
intptr_t native_pc = GetAddressOf(block);
write_pos2 = EncodeUnsignedLeb128(write_pos2, native_pc - dex2pc_offset);
CHECK_EQ(stack_map_entry.dex_pc, it.DexPc());
++it;
}
- for (size_t i = 0; i < graph_->GetBlocks().Size(); ++i) {
- HBasicBlock* block = graph_->GetBlocks().Get(i);
+ for (HBasicBlock* block : graph_->GetBlocks()) {
if (block->IsCatchBlock()) {
CHECK_EQ(GetAddressOf(block), it2.NativePcOffset());
CHECK_EQ(block->GetDexPc(), it2.DexPc());
void CodeGenerator::RecordCatchBlockInfo() {
ArenaAllocator* arena = graph_->GetArena();
- for (size_t i = 0, e = block_order_->Size(); i < e; ++i) {
- HBasicBlock* block = block_order_->Get(i);
+ for (HBasicBlock* block : *block_order_) {
if (!block->IsCatchBlock()) {
continue;
}
size_t maximum_number_of_live_core_registers,
size_t maximum_number_of_live_fp_registers,
size_t number_of_out_slots,
- const GrowableArray<HBasicBlock*>& block_order);
+ const ArenaVector<HBasicBlock*>& block_order);
int32_t GetStackSlot(HLocal* local) const;
Location GetTemporaryLocation(HTemporary* temp) const;
StackMapStream stack_map_stream_;
// The order to use for code generation.
- const GrowableArray<HBasicBlock*>* block_order_;
+ const ArenaVector<HBasicBlock*>* block_order_;
// Whether we are using baseline.
bool is_baseline_;
stack_map_stream_.SetStackMapNativePcOffset(i, new_position);
}
// Adjust native pc offsets of block labels.
- for (size_t block_idx = 0u, end = block_order_->Size(); block_idx != end; ++block_idx) {
- HBasicBlock* block = block_order_->Get(block_idx);
+ for (HBasicBlock* block : *block_order_) {
// Get the label directly from block_labels_ rather than through GetLabelOf() to avoid
// FirstNonEmptyBlock() which could lead to adjusting a label more than once.
DCHECK_LT(static_cast<size_t>(block->GetBlockId()), block_labels_.Size());
}
void Initialize() OVERRIDE {
- block_labels_.SetSize(GetGraph()->GetBlocks().Size());
+ block_labels_.SetSize(GetGraph()->GetBlocks().size());
}
void Finalize(CodeAllocator* allocator) OVERRIDE;
void Initialize() OVERRIDE {
HGraph* graph = GetGraph();
- int length = graph->GetBlocks().Size();
+ int length = graph->GetBlocks().size();
block_labels_ = graph->GetArena()->AllocArray<vixl::Label>(length);
for (int i = 0; i < length; ++i) {
new(block_labels_ + i) vixl::Label();
}
void Initialize() OVERRIDE {
- block_labels_.SetSize(GetGraph()->GetBlocks().Size());
+ block_labels_.SetSize(GetGraph()->GetBlocks().size());
}
void Finalize(CodeAllocator* allocator) OVERRIDE;
}
void Initialize() OVERRIDE {
- block_labels_.SetSize(GetGraph()->GetBlocks().Size());
+ block_labels_.SetSize(GetGraph()->GetBlocks().size());
}
bool NeedsTwoRegisters(Primitive::Type type) const OVERRIDE {
}
void Initialize() OVERRIDE {
- block_labels_.SetSize(GetGraph()->GetBlocks().Size());
+ block_labels_.SetSize(GetGraph()->GetBlocks().size());
}
bool NeedsTwoRegisters(Primitive::Type type ATTRIBUTE_UNUSED) const OVERRIDE {
bool has_result,
Expected expected) {
// Tests may have already computed it.
- if (graph->GetReversePostOrder().IsEmpty()) {
+ if (graph->GetReversePostOrder().empty()) {
graph->BuildDominatorTree();
}
SsaLivenessAnalysis liveness(graph, codegen);
void HDeadCodeElimination::RemoveDeadBlocks() {
// Classify blocks as reachable/unreachable.
ArenaAllocator* allocator = graph_->GetArena();
- ArenaBitVector live_blocks(allocator, graph_->GetBlocks().Size(), false);
- ArenaBitVector affected_loops(allocator, graph_->GetBlocks().Size(), false);
+ ArenaBitVector live_blocks(allocator, graph_->GetBlocks().size(), false);
+ ArenaBitVector affected_loops(allocator, graph_->GetBlocks().size(), false);
MarkReachableBlocks(graph_->GetEntryBlock(), &live_blocks);
bool removed_one_or_more_blocks = false;
namespace art {
-static void TestCode(const uint16_t* data, const int* blocks, size_t blocks_length) {
+static void TestCode(const uint16_t* data, const uint32_t* blocks, size_t blocks_length) {
ArenaPool pool;
ArenaAllocator allocator(&pool);
HGraph* graph = CreateGraph(&allocator);
bool graph_built = builder.BuildGraph(*item);
ASSERT_TRUE(graph_built);
graph->BuildDominatorTree();
- ASSERT_EQ(graph->GetBlocks().Size(), blocks_length);
+ ASSERT_EQ(graph->GetBlocks().size(), blocks_length);
for (size_t i = 0, e = blocks_length; i < e; ++i) {
- if (blocks[i] == -1) {
- if (graph->GetBlocks().Get(i) == nullptr) {
+ if (blocks[i] == kInvalidBlockId) {
+ if (graph->GetBlock(i) == nullptr) {
// Dead block.
} else {
// Only the entry block has no dominator.
- ASSERT_EQ(nullptr, graph->GetBlocks().Get(i)->GetDominator());
- ASSERT_TRUE(graph->GetBlocks().Get(i)->IsEntryBlock());
+ ASSERT_EQ(nullptr, graph->GetBlock(i)->GetDominator());
+ ASSERT_TRUE(graph->GetBlock(i)->IsEntryBlock());
}
} else {
- ASSERT_NE(nullptr, graph->GetBlocks().Get(i)->GetDominator());
- ASSERT_EQ(blocks[i], graph->GetBlocks().Get(i)->GetDominator()->GetBlockId());
+ ASSERT_NE(nullptr, graph->GetBlock(i)->GetDominator());
+ ASSERT_EQ(blocks[i], graph->GetBlock(i)->GetDominator()->GetBlockId());
}
}
}
const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
Instruction::RETURN_VOID); // Block number 1
- const int dominators[] = {
- -1,
- 0,
- 1
+ const uint32_t dominators[] = {
+ kInvalidBlockId,
+ 0,
+ 1
};
TestCode(data, dominators, sizeof(dominators) / sizeof(int));
Instruction::GOTO | 0x100, // Block number 1
Instruction::RETURN_VOID); // Block number 2
- const int dominators[] = {
- -1,
- 0,
- 1,
- 2
+ const uint32_t dominators[] = {
+ kInvalidBlockId,
+ 0,
+ 1,
+ 2
};
TestCode(data, dominators, sizeof(dominators) / sizeof(int));
Instruction::GOTO | 0x100, // Block number 2
Instruction::RETURN_VOID); // Block number 3
- const int dominators[] = {
- -1,
- 0,
- 1,
- 2,
- 3
+ const uint32_t dominators[] = {
+ kInvalidBlockId,
+ 0,
+ 1,
+ 2,
+ 3
};
TestCode(data, dominators, sizeof(dominators) / sizeof(int));
Instruction::RETURN_VOID, // Block number 2
Instruction::GOTO | 0xFF00); // Block number 3
- const int dominators[] = {
- -1,
- 0,
- 3,
- 1,
- 2
+ const uint32_t dominators[] = {
+ kInvalidBlockId,
+ 0,
+ 3,
+ 1,
+ 2
};
TestCode(data1, dominators, sizeof(dominators) / sizeof(int));
Instruction::NOP,
Instruction::GOTO | 0xFF00);
- const int dominators[] = {
- -1,
- 0,
- -1
+ const uint32_t dominators[] = {
+ kInvalidBlockId,
+ 0,
+ kInvalidBlockId
};
TestCode(data1, dominators, sizeof(dominators) / sizeof(int));
Instruction::GOTO | 0xFE00); // Block number 2
- const int dominators[] = {
- -1,
- 0,
- -1,
- 1
+ const uint32_t dominators[] = {
+ kInvalidBlockId,
+ 0,
+ kInvalidBlockId,
+ 1
};
TestCode(data, dominators, sizeof(dominators) / sizeof(int));
Instruction::GOTO | 0x100,
Instruction::RETURN_VOID);
- const int dominators[] = {
- -1,
- 0,
- 1,
- 1,
- 3,
- 1, // Synthesized block to avoid critical edge.
+ const uint32_t dominators[] = {
+ kInvalidBlockId,
+ 0,
+ 1,
+ 1,
+ 3,
+ 1, // Synthesized block to avoid critical edge.
};
TestCode(data, dominators, sizeof(dominators) / sizeof(int));
Instruction::GOTO | 0x100, // Block number 2
Instruction::GOTO | 0xFF00); // Block number 3
- const int dominators[] = {
- -1,
- 0,
- 1,
- 1,
- -1, // exit block is not dominated by any block due to the spin loop.
- 1, // block to avoid critical edge.
- 1 // block to avoid critical edge.
+ const uint32_t dominators[] = {
+ kInvalidBlockId,
+ 0,
+ 1,
+ 1,
+ kInvalidBlockId, // exit block is not dominated by any block due to the spin loop.
+ 1, // block to avoid critical edge.
+ 1 // block to avoid critical edge.
};
TestCode(data, dominators, sizeof(dominators) / sizeof(int));
Instruction::GOTO | 0x100, // Block number 3
Instruction::GOTO | 0xFF00); // Block number 4
- const int dominators[] = {
- -1,
- 0,
- 1,
- 1,
- 1,
- -1, // exit block is not dominated by any block due to the spin loop.
- 1 // block to avoid critical edge.
+ const uint32_t dominators[] = {
+ kInvalidBlockId,
+ 0,
+ 1,
+ 1,
+ 1,
+ kInvalidBlockId, // exit block is not dominated by any block due to the spin loop.
+ 1 // block to avoid critical edge.
};
TestCode(data, dominators, sizeof(dominators) / sizeof(int));
Instruction::GOTO | 0x100, // Block number 3
Instruction::GOTO | 0xFE00); // Block number 4
- const int dominators[] = {
- -1,
- 0,
- 1,
- 1,
- 1,
- -1, // exit block is not dominated by any block due to the spin loop.
- 1 // block to avoid critical edge.
+ const uint32_t dominators[] = {
+ kInvalidBlockId,
+ 0,
+ 1,
+ 1,
+ 1,
+ kInvalidBlockId, // exit block is not dominated by any block due to the spin loop.
+ 1 // block to avoid critical edge.
};
TestCode(data, dominators, sizeof(dominators) / sizeof(int));
Instruction::GOTO | 0x100, // Block number 4
Instruction::RETURN_VOID); // Block number 5
- const int dominators[] = {
- -1,
- 0,
- 1,
- 2,
- 2,
- 1,
- 5, // Block number 5 dominates exit block
- 1, // block to avoid critical edge.
- 2 // block to avoid critical edge.
+ const uint32_t dominators[] = {
+ kInvalidBlockId,
+ 0,
+ 1,
+ 2,
+ 2,
+ 1,
+ 5, // Block number 5 dominates exit block
+ 1, // block to avoid critical edge.
+ 2 // block to avoid critical edge.
};
TestCode(data, dominators, sizeof(dominators) / sizeof(int));
ArenaPool arena;
ArenaAllocator allocator(&arena);
HGraph* graph = TestCode(data, &allocator);
- for (size_t i = 0, e = graph->GetBlocks().Size(); i < e; ++i) {
- ASSERT_EQ(graph->GetBlocks().Get(i)->GetLoopInformation(), nullptr);
+ for (HBasicBlock* block : graph->GetBlocks()) {
+ ASSERT_EQ(block->GetLoopInformation(), nullptr);
}
}
ArenaPool arena;
ArenaAllocator allocator(&arena);
HGraph* graph = TestCode(data, &allocator);
- for (size_t i = 0, e = graph->GetBlocks().Size(); i < e; ++i) {
- ASSERT_EQ(graph->GetBlocks().Get(i)->GetLoopInformation(), nullptr);
+ for (HBasicBlock* block : graph->GetBlocks()) {
+ ASSERT_EQ(block->GetLoopInformation(), nullptr);
}
}
ArenaPool arena;
ArenaAllocator allocator(&arena);
HGraph* graph = TestCode(data, &allocator);
- for (size_t i = 0, e = graph->GetBlocks().Size(); i < e; ++i) {
- ASSERT_EQ(graph->GetBlocks().Get(i)->GetLoopInformation(), nullptr);
+ for (HBasicBlock* block : graph->GetBlocks()) {
+ ASSERT_EQ(block->GetLoopInformation(), nullptr);
}
}
ArenaPool arena;
ArenaAllocator allocator(&arena);
HGraph* graph = TestCode(data, &allocator);
- for (size_t i = 0, e = graph->GetBlocks().Size(); i < e; ++i) {
- ASSERT_EQ(graph->GetBlocks().Get(i)->GetLoopInformation(), nullptr);
+ for (HBasicBlock* block : graph->GetBlocks()) {
+ ASSERT_EQ(block->GetLoopInformation(), nullptr);
}
}
ArenaPool arena;
ArenaAllocator allocator(&arena);
HGraph* graph = TestCode(data, &allocator);
- for (size_t i = 0, e = graph->GetBlocks().Size(); i < e; ++i) {
- ASSERT_EQ(graph->GetBlocks().Get(i)->GetLoopInformation(), nullptr);
+ for (HBasicBlock* block : graph->GetBlocks()) {
+ ASSERT_EQ(block->GetLoopInformation(), nullptr);
}
}
static void TestBlock(HGraph* graph,
- int block_id,
+ uint32_t block_id,
bool is_loop_header,
- int parent_loop_header_id,
+ uint32_t parent_loop_header_id,
const int* blocks_in_loop = nullptr,
size_t number_of_blocks = 0) {
- HBasicBlock* block = graph->GetBlocks().Get(block_id);
+ HBasicBlock* block = graph->GetBlock(block_id);
ASSERT_EQ(block->IsLoopHeader(), is_loop_header);
- if (parent_loop_header_id == -1) {
+ if (parent_loop_header_id == kInvalidBlockId) {
ASSERT_EQ(block->GetLoopInformation(), nullptr);
} else {
ASSERT_EQ(block->GetLoopInformation()->GetHeader()->GetBlockId(), parent_loop_header_id);
ArenaAllocator allocator(&arena);
HGraph* graph = TestCode(data, &allocator);
- TestBlock(graph, 0, false, -1); // entry block
- TestBlock(graph, 1, false, -1); // pre header
+ TestBlock(graph, 0, false, kInvalidBlockId); // entry block
+ TestBlock(graph, 1, false, kInvalidBlockId); // pre header
const int blocks2[] = {2, 3};
- TestBlock(graph, 2, true, 2, blocks2, 2); // loop header
- TestBlock(graph, 3, false, 2); // block in loop
- TestBlock(graph, 4, false, -1); // return block
- TestBlock(graph, 5, false, -1); // exit block
+ TestBlock(graph, 2, true, 2, blocks2, 2); // loop header
+ TestBlock(graph, 3, false, 2); // block in loop
+ TestBlock(graph, 4, false, kInvalidBlockId); // return block
+ TestBlock(graph, 5, false, kInvalidBlockId); // exit block
}
TEST(FindLoopsTest, Loop2) {
ArenaAllocator allocator(&arena);
HGraph* graph = TestCode(data, &allocator);
- TestBlock(graph, 0, false, -1); // entry block
- TestBlock(graph, 1, false, -1); // goto block
+ TestBlock(graph, 0, false, kInvalidBlockId); // entry block
+ TestBlock(graph, 1, false, kInvalidBlockId); // goto block
const int blocks2[] = {2, 3};
- TestBlock(graph, 2, true, 2, blocks2, 2); // loop header
- TestBlock(graph, 3, false, 2); // block in loop
- TestBlock(graph, 4, false, -1); // pre header
- TestBlock(graph, 5, false, -1); // return block
- TestBlock(graph, 6, false, -1); // exit block
+ TestBlock(graph, 2, true, 2, blocks2, 2); // loop header
+ TestBlock(graph, 3, false, 2); // block in loop
+ TestBlock(graph, 4, false, kInvalidBlockId); // pre header
+ TestBlock(graph, 5, false, kInvalidBlockId); // return block
+ TestBlock(graph, 6, false, kInvalidBlockId); // exit block
}
TEST(FindLoopsTest, Loop3) {
ArenaAllocator allocator(&arena);
HGraph* graph = TestCode(data, &allocator);
- TestBlock(graph, 0, false, -1); // entry block
- TestBlock(graph, 1, false, -1); // goto block
- TestBlock(graph, 2, false, -1);
+ TestBlock(graph, 0, false, kInvalidBlockId); // entry block
+ TestBlock(graph, 1, false, kInvalidBlockId); // goto block
+ TestBlock(graph, 2, false, kInvalidBlockId);
const int blocks2[] = {3, 4};
- TestBlock(graph, 3, true, 3, blocks2, 2); // loop header
- TestBlock(graph, 4, false, 3); // block in loop
- TestBlock(graph, 5, false, -1); // pre header
- TestBlock(graph, 6, false, -1); // return block
- TestBlock(graph, 7, false, -1); // exit block
- TestBlock(graph, 8, false, -1); // synthesized pre header
+ TestBlock(graph, 3, true, 3, blocks2, 2); // loop header
+ TestBlock(graph, 4, false, 3); // block in loop
+ TestBlock(graph, 5, false, kInvalidBlockId); // pre header
+ TestBlock(graph, 6, false, kInvalidBlockId); // return block
+ TestBlock(graph, 7, false, kInvalidBlockId); // exit block
+ TestBlock(graph, 8, false, kInvalidBlockId); // synthesized pre header
}
TEST(FindLoopsTest, Loop4) {
ArenaAllocator allocator(&arena);
HGraph* graph = TestCode(data, &allocator);
- TestBlock(graph, 0, false, -1); // entry block
- TestBlock(graph, 1, false, -1); // pre header
+ TestBlock(graph, 0, false, kInvalidBlockId); // entry block
+ TestBlock(graph, 1, false, kInvalidBlockId); // pre header
const int blocks2[] = {2, 3, 4, 5};
TestBlock(graph, 2, true, 2, blocks2, arraysize(blocks2)); // loop header
- TestBlock(graph, 3, false, 2); // block in loop
- TestBlock(graph, 4, false, 2); // back edge
- TestBlock(graph, 5, false, 2); // back edge
- TestBlock(graph, 6, false, -1); // return block
- TestBlock(graph, 7, false, -1); // exit block
+ TestBlock(graph, 3, false, 2); // block in loop
+ TestBlock(graph, 4, false, 2); // back edge
+ TestBlock(graph, 5, false, 2); // back edge
+ TestBlock(graph, 6, false, kInvalidBlockId); // return block
+ TestBlock(graph, 7, false, kInvalidBlockId); // exit block
}
ArenaAllocator allocator(&arena);
HGraph* graph = TestCode(data, &allocator);
- TestBlock(graph, 0, false, -1); // entry block
- TestBlock(graph, 1, false, -1); // pre header
+ TestBlock(graph, 0, false, kInvalidBlockId); // entry block
+ TestBlock(graph, 1, false, kInvalidBlockId); // pre header
const int blocks2[] = {2, 3, 5};
- TestBlock(graph, 2, true, 2, blocks2, 3); // loop header
- TestBlock(graph, 3, false, 2); // block in loop
- TestBlock(graph, 4, false, -1); // loop exit
- TestBlock(graph, 5, false, 2); // back edge
- TestBlock(graph, 6, false, -1); // return block
- TestBlock(graph, 7, false, -1); // exit block
- TestBlock(graph, 8, false, -1); // synthesized block at the loop exit
+ TestBlock(graph, 2, true, 2, blocks2, 3); // loop header
+ TestBlock(graph, 3, false, 2); // block in loop
+ TestBlock(graph, 4, false, kInvalidBlockId); // loop exit
+ TestBlock(graph, 5, false, 2); // back edge
+ TestBlock(graph, 6, false, kInvalidBlockId); // return block
+ TestBlock(graph, 7, false, kInvalidBlockId); // exit block
+ TestBlock(graph, 8, false, kInvalidBlockId); // synthesized block at the loop exit
}
TEST(FindLoopsTest, InnerLoop) {
ArenaAllocator allocator(&arena);
HGraph* graph = TestCode(data, &allocator);
- TestBlock(graph, 0, false, -1); // entry block
- TestBlock(graph, 1, false, -1); // pre header of outer loop
+ TestBlock(graph, 0, false, kInvalidBlockId); // entry block
+ TestBlock(graph, 1, false, kInvalidBlockId); // pre header of outer loop
const int blocks2[] = {2, 3, 4, 5, 8};
- TestBlock(graph, 2, true, 2, blocks2, 5); // outer loop header
+ TestBlock(graph, 2, true, 2, blocks2, 5); // outer loop header
const int blocks3[] = {3, 4};
- TestBlock(graph, 3, true, 3, blocks3, 2); // inner loop header
- TestBlock(graph, 4, false, 3); // back edge on inner loop
- TestBlock(graph, 5, false, 2); // back edge on outer loop
- TestBlock(graph, 6, false, -1); // return block
- TestBlock(graph, 7, false, -1); // exit block
- TestBlock(graph, 8, false, 2); // synthesized block as pre header of inner loop
-
- ASSERT_TRUE(graph->GetBlocks().Get(3)->GetLoopInformation()->IsIn(
- *graph->GetBlocks().Get(2)->GetLoopInformation()));
- ASSERT_FALSE(graph->GetBlocks().Get(2)->GetLoopInformation()->IsIn(
- *graph->GetBlocks().Get(3)->GetLoopInformation()));
+ TestBlock(graph, 3, true, 3, blocks3, 2); // inner loop header
+ TestBlock(graph, 4, false, 3); // back edge on inner loop
+ TestBlock(graph, 5, false, 2); // back edge on outer loop
+ TestBlock(graph, 6, false, kInvalidBlockId); // return block
+ TestBlock(graph, 7, false, kInvalidBlockId); // exit block
+ TestBlock(graph, 8, false, 2); // synthesized block as pre header of inner loop
+
+ ASSERT_TRUE(graph->GetBlock(3)->GetLoopInformation()->IsIn(
+ *graph->GetBlock(2)->GetLoopInformation()));
+ ASSERT_FALSE(graph->GetBlock(2)->GetLoopInformation()->IsIn(
+ *graph->GetBlock(3)->GetLoopInformation()));
}
TEST(FindLoopsTest, TwoLoops) {
ArenaAllocator allocator(&arena);
HGraph* graph = TestCode(data, &allocator);
- TestBlock(graph, 0, false, -1); // entry block
- TestBlock(graph, 1, false, -1); // pre header of first loop
+ TestBlock(graph, 0, false, kInvalidBlockId); // entry block
+ TestBlock(graph, 1, false, kInvalidBlockId); // pre header of first loop
const int blocks2[] = {2, 3};
- TestBlock(graph, 2, true, 2, blocks2, 2); // first loop header
- TestBlock(graph, 3, false, 2); // back edge of first loop
+ TestBlock(graph, 2, true, 2, blocks2, 2); // first loop header
+ TestBlock(graph, 3, false, 2); // back edge of first loop
const int blocks4[] = {4, 5};
- TestBlock(graph, 4, true, 4, blocks4, 2); // second loop header
- TestBlock(graph, 5, false, 4); // back edge of second loop
- TestBlock(graph, 6, false, -1); // return block
- TestBlock(graph, 7, false, -1); // exit block
-
- ASSERT_FALSE(graph->GetBlocks().Get(4)->GetLoopInformation()->IsIn(
- *graph->GetBlocks().Get(2)->GetLoopInformation()));
- ASSERT_FALSE(graph->GetBlocks().Get(2)->GetLoopInformation()->IsIn(
- *graph->GetBlocks().Get(4)->GetLoopInformation()));
+ TestBlock(graph, 4, true, 4, blocks4, 2); // second loop header
+ TestBlock(graph, 5, false, 4); // back edge of second loop
+ TestBlock(graph, 6, false, kInvalidBlockId); // return block
+ TestBlock(graph, 7, false, kInvalidBlockId); // exit block
+
+ ASSERT_FALSE(graph->GetBlock(4)->GetLoopInformation()->IsIn(
+ *graph->GetBlock(2)->GetLoopInformation()));
+ ASSERT_FALSE(graph->GetBlock(2)->GetLoopInformation()->IsIn(
+ *graph->GetBlock(4)->GetLoopInformation()));
}
TEST(FindLoopsTest, NonNaturalLoop) {
ArenaPool arena;
ArenaAllocator allocator(&arena);
HGraph* graph = TestCode(data, &allocator);
- ASSERT_TRUE(graph->GetBlocks().Get(3)->IsLoopHeader());
- HLoopInformation* info = graph->GetBlocks().Get(3)->GetLoopInformation();
- ASSERT_FALSE(info->GetHeader()->Dominates(info->GetBackEdges().Get(0)));
+ ASSERT_TRUE(graph->GetBlock(3)->IsLoopHeader());
+ HLoopInformation* info = graph->GetBlock(3)->GetLoopInformation();
+ ASSERT_EQ(1u, info->NumberOfBackEdges());
+ ASSERT_FALSE(info->GetHeader()->Dominates(info->GetBackEdges()[0]));
}
TEST(FindLoopsTest, DoWhileLoop) {
ArenaAllocator allocator(&arena);
HGraph* graph = TestCode(data, &allocator);
- TestBlock(graph, 0, false, -1); // entry block
- TestBlock(graph, 1, false, -1); // pre header of first loop
+ TestBlock(graph, 0, false, kInvalidBlockId); // entry block
+ TestBlock(graph, 1, false, kInvalidBlockId); // pre header of first loop
const int blocks2[] = {2, 3, 6};
- TestBlock(graph, 2, true, 2, blocks2, 3); // loop header
- TestBlock(graph, 3, false, 2); // back edge of first loop
- TestBlock(graph, 4, false, -1); // return block
- TestBlock(graph, 5, false, -1); // exit block
- TestBlock(graph, 6, false, 2); // synthesized block to avoid a critical edge
+ TestBlock(graph, 2, true, 2, blocks2, 3); // loop header
+ TestBlock(graph, 3, false, 2); // back edge of first loop
+ TestBlock(graph, 4, false, kInvalidBlockId); // return block
+ TestBlock(graph, 5, false, kInvalidBlockId); // exit block
+ TestBlock(graph, 6, false, 2); // synthesized block to avoid a critical edge
}
} // namespace art
const ArenaBitVector& loop_blocks = loop_information->GetBlocks();
// Ensure back edges belong to the loop.
- size_t num_back_edges = loop_information->GetBackEdges().Size();
- if (num_back_edges == 0) {
+ if (loop_information->NumberOfBackEdges() == 0) {
AddError(StringPrintf(
"Loop defined by header %d has no back edge.",
id));
} else {
- for (size_t i = 0; i < num_back_edges; ++i) {
- int back_edge_id = loop_information->GetBackEdges().Get(i)->GetBlockId();
+ for (HBasicBlock* back_edge : loop_information->GetBackEdges()) {
+ int back_edge_id = back_edge->GetBlockId();
if (!loop_blocks.IsBitSet(back_edge_id)) {
AddError(StringPrintf(
"Loop defined by header %d has an invalid back edge %d.",
// Ensure all blocks in the loop are live and dominated by the loop header.
for (uint32_t i : loop_blocks.Indexes()) {
- HBasicBlock* loop_block = GetGraph()->GetBlocks().Get(i);
+ HBasicBlock* loop_block = GetGraph()->GetBlock(i);
if (loop_block == nullptr) {
AddError(StringPrintf("Loop defined by header %d contains a previously removed block %d.",
id,
bool is_after_pass,
bool graph_in_bad_state) const {
DCHECK(output_ != nullptr);
- if (!graph_->GetBlocks().IsEmpty()) {
+ if (!graph_->GetBlocks().empty()) {
HGraphVisualizerPrinter printer(graph_,
*output_,
pass_name,
void HGraphVisualizer::DumpGraphWithDisassembly() const {
DCHECK(output_ != nullptr);
- if (!graph_->GetBlocks().IsEmpty()) {
+ if (!graph_->GetBlocks().empty()) {
HGraphVisualizerPrinter printer(graph_,
*output_,
"disassembly",
: graph_(graph),
allocator_(allocator),
side_effects_(side_effects),
- sets_(allocator, graph->GetBlocks().Size(), nullptr) {}
+ sets_(allocator, graph->GetBlocks().size(), nullptr) {}
void Run();
// doing some logic in the runtime to discover if a method could have been inlined.
return;
}
- const GrowableArray<HBasicBlock*>& blocks = graph_->GetReversePostOrder();
- HBasicBlock* next_block = blocks.Get(0);
- for (size_t i = 0; i < blocks.Size(); ++i) {
+ const ArenaVector<HBasicBlock*>& blocks = graph_->GetReversePostOrder();
+ DCHECK(!blocks.empty());
+ HBasicBlock* next_block = blocks[0];
+ for (size_t i = 0; i < blocks.size(); ++i) {
// Because we are changing the graph when inlining, we need to remember the next block.
// This avoids doing the inlining work again on the inlined blocks.
- if (blocks.Get(i) != next_block) {
+ if (blocks[i] != next_block) {
continue;
}
HBasicBlock* block = next_block;
- next_block = (i == blocks.Size() - 1) ? nullptr : blocks.Get(i + 1);
+ next_block = (i == blocks.size() - 1) ? nullptr : blocks[i + 1];
for (HInstruction* instruction = block->GetFirstInstruction(); instruction != nullptr;) {
HInstruction* next = instruction->GetNext();
HInvoke* call = instruction->AsInvoke();
void LICM::Run() {
DCHECK(side_effects_.HasRun());
// Only used during debug.
- ArenaBitVector visited(graph_->GetArena(), graph_->GetBlocks().Size(), false);
+ ArenaBitVector visited(graph_->GetArena(), graph_->GetBlocks().size(), false);
// Post order visit to visit inner loops before outer loops.
for (HPostOrderIterator it(*graph_); !it.Done(); it.Advance()) {
namespace art {
-static void TestCode(const uint16_t* data, const int* expected_order, size_t number_of_blocks) {
+template <size_t number_of_blocks>
+static void TestCode(const uint16_t* data, const uint32_t (&expected_order)[number_of_blocks]) {
ArenaPool pool;
ArenaAllocator allocator(&pool);
HGraph* graph = CreateGraph(&allocator);
SsaLivenessAnalysis liveness(graph, &codegen);
liveness.Analyze();
- ASSERT_EQ(graph->GetLinearOrder().Size(), number_of_blocks);
+ ASSERT_EQ(graph->GetLinearOrder().size(), number_of_blocks);
for (size_t i = 0; i < number_of_blocks; ++i) {
- ASSERT_EQ(graph->GetLinearOrder().Get(i)->GetBlockId(), expected_order[i]);
+ ASSERT_EQ(graph->GetLinearOrder()[i]->GetBlockId(), expected_order[i]);
}
}
Instruction::GOTO | 0xFE00,
Instruction::RETURN_VOID);
- const int blocks[] = {0, 1, 2, 7, 3, 4, 8, 5, 6};
- TestCode(data, blocks, 9);
+ const uint32_t blocks[] = {0, 1, 2, 7, 3, 4, 8, 5, 6};
+ TestCode(data, blocks);
}
TEST(LinearizeTest, CFG2) {
Instruction::IF_EQ, 0xFFFD,
Instruction::GOTO | 0xFE00);
- const int blocks[] = {0, 1, 2, 7, 4, 5, 8, 3, 6};
- TestCode(data, blocks, 9);
+ const uint32_t blocks[] = {0, 1, 2, 7, 4, 5, 8, 3, 6};
+ TestCode(data, blocks);
}
TEST(LinearizeTest, CFG3) {
Instruction::IF_EQ, 0xFFFC,
Instruction::GOTO | 0xFD00);
- const int blocks[] = {0, 1, 2, 8, 5, 6, 4, 9, 3, 7};
- TestCode(data, blocks, 10);
+ const uint32_t blocks[] = {0, 1, 2, 8, 5, 6, 4, 9, 3, 7};
+ TestCode(data, blocks);
}
TEST(LinearizeTest, CFG4) {
Instruction::GOTO | 0xFE00,
Instruction::RETURN_VOID);
- const int blocks[] = {0, 1, 2, 8, 3, 10, 4, 5, 11, 9, 6, 7};
- TestCode(data, blocks, 12);
+ const uint32_t blocks[] = {0, 1, 2, 8, 3, 10, 4, 5, 11, 9, 6, 7};
+ TestCode(data, blocks);
}
TEST(LinearizeTest, CFG5) {
Instruction::IF_EQ, 0xFFFE,
Instruction::GOTO | 0xFE00);
- const int blocks[] = {0, 1, 2, 8, 4, 10, 5, 6, 11, 9, 3, 7};
- TestCode(data, blocks, 12);
+ const uint32_t blocks[] = {0, 1, 2, 8, 4, 10, 5, 6, 11, 9, 3, 7};
+ TestCode(data, blocks);
}
TEST(LinearizeTest, CFG6) {
Instruction::RETURN_VOID,
Instruction::GOTO | 0xFA00);
- const int blocks[] = {0, 1, 2, 3, 4, 6, 9, 8, 5, 7};
- TestCode(data, blocks, arraysize(blocks));
+ const uint32_t blocks[] = {0, 1, 2, 3, 4, 6, 9, 8, 5, 7};
+ TestCode(data, blocks);
}
TEST(LinearizeTest, CFG7) {
Instruction::RETURN_VOID,
Instruction::GOTO | 0xFA00);
- const int blocks[] = {0, 1, 2, 3, 4, 9, 8, 6, 5, 7};
- TestCode(data, blocks, arraysize(blocks));
+ const uint32_t blocks[] = {0, 1, 2, 3, 4, 9, 8, 6, 5, 7};
+ TestCode(data, blocks);
}
} // namespace art
ASSERT_EQ(2u, range->GetStart());
// Last use is the return instruction.
ASSERT_EQ(8u, range->GetEnd());
- HBasicBlock* block = graph->GetBlocks().Get(1);
+ HBasicBlock* block = graph->GetBlock(1);
ASSERT_TRUE(block->GetLastInstruction()->IsReturn());
ASSERT_EQ(8u, block->GetLastInstruction()->GetLifetimePosition());
ASSERT_TRUE(range->GetNext() == nullptr);
ASSERT_EQ(2u, range->GetStart());
// Last use is the return instruction.
ASSERT_EQ(22u, range->GetEnd());
- HBasicBlock* block = graph->GetBlocks().Get(3);
+ HBasicBlock* block = graph->GetBlock(3);
ASSERT_TRUE(block->GetLastInstruction()->IsReturn());
ASSERT_EQ(22u, block->GetLastInstruction()->GetLifetimePosition());
ASSERT_TRUE(range->GetNext() == nullptr);
* A Location is an abstraction over the potential location
* of an instruction. It could be in register or stack.
*/
-class Location : public ValueObject {
+class Location {
public:
enum OutputOverlap {
kOutputOverlap,
DCHECK(!IsValid());
}
- Location(const Location& other) : ValueObject(), value_(other.value_) {}
+ Location(const Location& other) : value_(other.value_) {}
Location& operator=(const Location& other) {
value_ = other.value_;
namespace art {
void HGraph::AddBlock(HBasicBlock* block) {
- block->SetBlockId(blocks_.Size());
- blocks_.Add(block);
+ block->SetBlockId(blocks_.size());
+ blocks_.push_back(block);
}
void HGraph::FindBackEdges(ArenaBitVector* visited) {
- ArenaBitVector visiting(arena_, blocks_.Size(), false);
+ ArenaBitVector visiting(arena_, blocks_.size(), false);
VisitBlockForBackEdges(entry_block_, visited, &visiting);
}
}
void HGraph::RemoveInstructionsAsUsersFromDeadBlocks(const ArenaBitVector& visited) const {
- for (size_t i = 0; i < blocks_.Size(); ++i) {
+ for (size_t i = 0; i < blocks_.size(); ++i) {
if (!visited.IsBitSet(i)) {
- HBasicBlock* block = blocks_.Get(i);
+ HBasicBlock* block = GetBlock(i);
DCHECK(block->GetPhis().IsEmpty()) << "Phis are not inserted at this stage";
for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) {
RemoveAsUser(it.Current());
}
void HGraph::RemoveDeadBlocks(const ArenaBitVector& visited) {
- for (size_t i = 0; i < blocks_.Size(); ++i) {
+ for (size_t i = 0; i < blocks_.size(); ++i) {
if (!visited.IsBitSet(i)) {
- HBasicBlock* block = blocks_.Get(i);
+ HBasicBlock* block = GetBlock(i);
// We only need to update the successor, which might be live.
for (HBasicBlock* successor : block->GetSuccessors()) {
successor->RemovePredecessor(block);
}
// Remove the block from the list of blocks, so that further analyses
// never see it.
- blocks_.Put(i, nullptr);
+ blocks_[i] = nullptr;
}
}
}
// collect both normal- and exceptional-flow values at the same time.
SimplifyCatchBlocks();
- ArenaBitVector visited(arena_, blocks_.Size(), false);
+ ArenaBitVector visited(arena_, blocks_.size(), false);
// (2) Find the back edges in the graph doing a DFS traversal.
FindBackEdges(&visited);
for (HReversePostOrderIterator it(*this); !it.Done(); it.Advance()) {
it.Current()->ClearDominanceInformation();
}
- reverse_post_order_.Reset();
+ reverse_post_order_.clear();
}
void HBasicBlock::ClearDominanceInformation() {
}
void HGraph::ComputeDominanceInformation() {
- DCHECK(reverse_post_order_.IsEmpty());
- GrowableArray<size_t> visits(arena_, blocks_.Size());
- visits.SetSize(blocks_.Size());
- reverse_post_order_.Add(entry_block_);
+ DCHECK(reverse_post_order_.empty());
+ reverse_post_order_.reserve(blocks_.size());
+ ArenaVector<size_t> visits(blocks_.size(), 0u, arena_->Adapter());
+ reverse_post_order_.push_back(entry_block_);
for (HBasicBlock* successor : entry_block_->GetSuccessors()) {
VisitBlockForDominatorTree(successor, entry_block_, &visits);
}
}
HBasicBlock* HGraph::FindCommonDominator(HBasicBlock* first, HBasicBlock* second) const {
- ArenaBitVector visited(arena_, blocks_.Size(), false);
+ ArenaBitVector visited(arena_, blocks_.size(), false);
// Walk the dominator tree of the first block and mark the visited blocks.
while (first != nullptr) {
visited.SetBit(first->GetBlockId());
void HGraph::VisitBlockForDominatorTree(HBasicBlock* block,
HBasicBlock* predecessor,
- GrowableArray<size_t>* visits) {
+ ArenaVector<size_t>* visits) {
if (block->GetDominator() == nullptr) {
block->SetDominator(predecessor);
} else {
block->SetDominator(FindCommonDominator(block->GetDominator(), predecessor));
}
- visits->Increment(block->GetBlockId());
// Once all the forward edges have been visited, we know the immediate
// dominator of the block. We can then start visiting its successors.
- if (visits->Get(block->GetBlockId()) ==
+ DCHECK_LT(block->GetBlockId(), visits->size());
+ if (++(*visits)[block->GetBlockId()] ==
block->GetPredecessors().size() - block->NumberOfBackEdges()) {
block->GetDominator()->AddDominatedBlock(block);
- reverse_post_order_.Add(block);
+ reverse_post_order_.push_back(block);
for (HBasicBlock* successor : block->GetSuccessors()) {
VisitBlockForDominatorTree(successor, block, visits);
}
}
void HGraph::TransformToSsa() {
- DCHECK(!reverse_post_order_.IsEmpty());
+ DCHECK(!reverse_post_order_.empty());
SsaBuilder ssa_builder(this);
ssa_builder.BuildSsa();
}
}
void HGraph::SimplifyCatchBlocks() {
- for (size_t i = 0; i < blocks_.Size(); ++i) {
- HBasicBlock* catch_block = blocks_.Get(i);
+ for (HBasicBlock* catch_block : blocks_) {
if (!catch_block->IsCatchBlock()) {
continue;
}
// Simplify the CFG for future analysis, and code generation:
// (1): Split critical edges.
// (2): Simplify loops by having only one back edge, and one preheader.
- for (size_t i = 0; i < blocks_.Size(); ++i) {
- HBasicBlock* block = blocks_.Get(i);
+ for (HBasicBlock* block : blocks_) {
if (block == nullptr) continue;
if (block->NumberOfNormalSuccessors() > 1) {
for (size_t j = 0; j < block->GetSuccessors().size(); ++j) {
bool HLoopInformation::Populate() {
DCHECK_EQ(blocks_.NumSetBits(), 0u) << "Loop information has already been populated";
- for (size_t i = 0, e = GetBackEdges().Size(); i < e; ++i) {
- HBasicBlock* back_edge = GetBackEdges().Get(i);
+ for (HBasicBlock* back_edge : GetBackEdges()) {
DCHECK(back_edge->GetDominator() != nullptr);
if (!header_->Dominates(back_edge)) {
// This loop is not natural. Do not bother going further.
void HLoopInformation::Update() {
HGraph* graph = header_->GetGraph();
for (uint32_t id : blocks_.Indexes()) {
- HBasicBlock* block = graph->GetBlocks().Get(id);
+ HBasicBlock* block = graph->GetBlock(id);
// Reset loop information of non-header blocks inside the loop, except
// members of inner nested loops because those should already have been
// updated by their own LoopInformation.
}
blocks_.ClearAllBits();
- if (back_edges_.IsEmpty()) {
+ if (back_edges_.empty()) {
// The loop has been dismantled, delete its suspend check and remove info
// from the header.
DCHECK(HasSuspendCheck());
suspend_check_ = nullptr;
} else {
if (kIsDebugBuild) {
- for (size_t i = 0, e = back_edges_.Size(); i < e; ++i) {
- DCHECK(header_->Dominates(back_edges_.Get(i)));
+ for (HBasicBlock* back_edge : back_edges_) {
+ DCHECK(header_->Dominates(back_edge));
}
}
// This loop still has reachable back edges. Repopulate the list of blocks.
size_t HLoopInformation::GetLifetimeEnd() const {
size_t last_position = 0;
- for (size_t i = 0, e = back_edges_.Size(); i < e; ++i) {
- last_position = std::max(back_edges_.Get(i)->GetLifetimeEnd(), last_position);
+ for (HBasicBlock* back_edge : GetBackEdges()) {
+ last_position = std::max(back_edge->GetLifetimeEnd(), last_position);
}
return last_position;
}
}
void HEnvironment::RemoveAsUserOfInput(size_t index) const {
- const HUserRecord<HEnvironment*> user_record = vregs_.Get(index);
+ DCHECK_LT(index, Size());
+ const HUserRecord<HEnvironment*>& user_record = vregs_[index];
user_record.GetInstruction()->RemoveEnvironmentUser(user_record.GetUseNode());
}
void HPhi::AddInput(HInstruction* input) {
DCHECK(input->GetBlock() != nullptr);
- inputs_.Add(HUserRecord<HInstruction*>(input));
- input->AddUseAt(this, inputs_.Size() - 1);
+ inputs_.push_back(HUserRecord<HInstruction*>(input));
+ input->AddUseAt(this, inputs_.size() - 1);
}
void HPhi::RemoveInputAt(size_t index) {
RemoveAsUserOfInput(index);
- inputs_.DeleteAt(index);
+ inputs_.erase(inputs_.begin() + index);
for (size_t i = index, e = InputCount(); i < e; ++i) {
+ DCHECK_EQ(InputRecordAt(i).GetUseNode()->GetIndex(), i + 1u);
InputRecordAt(i).GetUseNode()->SetIndex(i);
}
}
#undef DEFINE_ACCEPT
void HGraphVisitor::VisitInsertionOrder() {
- const GrowableArray<HBasicBlock*>& blocks = graph_->GetBlocks();
- for (size_t i = 0 ; i < blocks.Size(); i++) {
- HBasicBlock* block = blocks.Get(i);
+ const ArenaVector<HBasicBlock*>& blocks = graph_->GetBlocks();
+ for (HBasicBlock* block : blocks) {
if (block != nullptr) {
VisitBasicBlock(block);
}
// Create space in `blocks` for adding `number_of_new_blocks` entries
// starting at location `at`. Blocks after `at` are moved accordingly.
-static void MakeRoomFor(GrowableArray<HBasicBlock*>* blocks,
+static void MakeRoomFor(ArenaVector<HBasicBlock*>* blocks,
size_t number_of_new_blocks,
- size_t at) {
- size_t old_size = blocks->Size();
+ size_t after) {
+ DCHECK_LT(after, blocks->size());
+ size_t old_size = blocks->size();
size_t new_size = old_size + number_of_new_blocks;
- blocks->SetSize(new_size);
- for (size_t i = old_size - 1, j = new_size - 1; i > at; --i, --j) {
- blocks->Put(j, blocks->Get(i));
- }
+ blocks->resize(new_size);
+ std::copy_backward(blocks->begin() + after + 1u, blocks->begin() + old_size, blocks->end());
}
void HGraph::DeleteDeadBlock(HBasicBlock* block) {
exit_block_ = nullptr;
}
- reverse_post_order_.Delete(block);
- blocks_.Put(block->GetBlockId(), nullptr);
+ RemoveElement(reverse_post_order_, block);
+ blocks_[block->GetBlockId()] = nullptr;
}
HInstruction* HGraph::InlineInto(HGraph* outer_graph, HInvoke* invoke) {
}
HInstruction* return_value = nullptr;
- if (GetBlocks().Size() == 3) {
+ if (GetBlocks().size() == 3) {
// Simple case of an entry block, a body block, and an exit block.
// Put the body block's instruction into `invoke`'s block.
- HBasicBlock* body = GetBlocks().Get(1);
- DCHECK(GetBlocks().Get(0)->IsEntryBlock());
- DCHECK(GetBlocks().Get(2)->IsExitBlock());
+ HBasicBlock* body = GetBlock(1);
+ DCHECK(GetBlock(0)->IsEntryBlock());
+ DCHECK(GetBlock(2)->IsExitBlock());
DCHECK(!body->IsExitBlock());
HInstruction* last = body->GetLastInstruction();
// We add the `to` block.
static constexpr int kNumberOfNewBlocksInCaller = 1;
- size_t blocks_added = (reverse_post_order_.Size() - kNumberOfSkippedBlocksInCallee)
+ size_t blocks_added = (reverse_post_order_.size() - kNumberOfSkippedBlocksInCallee)
+ kNumberOfNewBlocksInCaller;
// Find the location of `at` in the outer graph's reverse post order. The new
// blocks will be added after it.
- size_t index_of_at = 0;
- while (outer_graph->reverse_post_order_.Get(index_of_at) != at) {
- index_of_at++;
- }
+ size_t index_of_at = IndexOfElement(outer_graph->reverse_post_order_, at);
MakeRoomFor(&outer_graph->reverse_post_order_, blocks_added, index_of_at);
// Do a reverse post order of the blocks in the callee and do (1), (2),
DCHECK(current->GetGraph() == this);
current->SetGraph(outer_graph);
outer_graph->AddBlock(current);
- outer_graph->reverse_post_order_.Put(++index_of_at, current);
+ outer_graph->reverse_post_order_[++index_of_at] = current;
if (info != nullptr) {
current->SetLoopInformation(info);
for (HLoopInformationOutwardIterator loop_it(*at); !loop_it.Done(); loop_it.Advance()) {
// Do (1), (2), and (3) to `to`.
to->SetGraph(outer_graph);
outer_graph->AddBlock(to);
- outer_graph->reverse_post_order_.Put(++index_of_at, to);
+ outer_graph->reverse_post_order_[++index_of_at] = to;
if (info != nullptr) {
to->SetLoopInformation(info);
for (HLoopInformationOutwardIterator loop_it(*at); !loop_it.Done(); loop_it.Advance()) {
new_pre_header->dominated_blocks_.push_back(header);
header->SetDominator(new_pre_header);
- size_t index_of_header = 0;
- while (reverse_post_order_.Get(index_of_header) != header) {
- index_of_header++;
- }
+ size_t index_of_header = IndexOfElement(reverse_post_order_, header);
MakeRoomFor(&reverse_post_order_, 4, index_of_header - 1);
- reverse_post_order_.Put(index_of_header++, if_block);
- reverse_post_order_.Put(index_of_header++, dummy_block);
- reverse_post_order_.Put(index_of_header++, deopt_block);
- reverse_post_order_.Put(index_of_header++, new_pre_header);
+ reverse_post_order_[index_of_header++] = if_block;
+ reverse_post_order_[index_of_header++] = dummy_block;
+ reverse_post_order_[index_of_header++] = deopt_block;
+ reverse_post_order_[index_of_header++] = new_pre_header;
HLoopInformation* info = pre_header->GetLoopInformation();
if (info != nullptr) {
bool debuggable = false,
int start_instruction_id = 0)
: arena_(arena),
- blocks_(arena, kDefaultNumberOfBlocks),
- reverse_post_order_(arena, kDefaultNumberOfBlocks),
- linear_order_(arena, kDefaultNumberOfBlocks),
+ blocks_(arena->Adapter(kArenaAllocBlockList)),
+ reverse_post_order_(arena->Adapter(kArenaAllocReversePostOrder)),
+ linear_order_(arena->Adapter(kArenaAllocLinearOrder)),
entry_block_(nullptr),
exit_block_(nullptr),
maximum_number_of_out_vregs_(0),
should_generate_constructor_barrier_(should_generate_constructor_barrier),
instruction_set_(instruction_set),
cached_null_constant_(nullptr),
- cached_int_constants_(std::less<int32_t>(), arena->Adapter()),
- cached_float_constants_(std::less<int32_t>(), arena->Adapter()),
- cached_long_constants_(std::less<int64_t>(), arena->Adapter()),
- cached_double_constants_(std::less<int64_t>(), arena->Adapter()),
- cached_current_method_(nullptr) {}
+ cached_int_constants_(std::less<int32_t>(), arena->Adapter(kArenaAllocConstantsMap)),
+ cached_float_constants_(std::less<int32_t>(), arena->Adapter(kArenaAllocConstantsMap)),
+ cached_long_constants_(std::less<int64_t>(), arena->Adapter(kArenaAllocConstantsMap)),
+ cached_double_constants_(std::less<int64_t>(), arena->Adapter(kArenaAllocConstantsMap)),
+ cached_current_method_(nullptr) {
+ blocks_.reserve(kDefaultNumberOfBlocks);
+ }
ArenaAllocator* GetArena() const { return arena_; }
- const GrowableArray<HBasicBlock*>& GetBlocks() const { return blocks_; }
- HBasicBlock* GetBlock(size_t id) const { return blocks_.Get(id); }
+ const ArenaVector<HBasicBlock*>& GetBlocks() const { return blocks_; }
+
+ HBasicBlock* GetBlock(size_t id) const {
+ DCHECK_LT(id, blocks_.size());
+ return blocks_[id];
+ }
bool IsInSsaForm() const { return in_ssa_form_; }
return number_of_vregs_ - number_of_in_vregs_;
}
- const GrowableArray<HBasicBlock*>& GetReversePostOrder() const {
+ const ArenaVector<HBasicBlock*>& GetReversePostOrder() const {
return reverse_post_order_;
}
- const GrowableArray<HBasicBlock*>& GetLinearOrder() const {
+ const ArenaVector<HBasicBlock*>& GetLinearOrder() const {
return linear_order_;
}
private:
void VisitBlockForDominatorTree(HBasicBlock* block,
HBasicBlock* predecessor,
- GrowableArray<size_t>* visits);
+ ArenaVector<size_t>* visits);
void FindBackEdges(ArenaBitVector* visited);
void VisitBlockForBackEdges(HBasicBlock* block,
ArenaBitVector* visited,
ArenaAllocator* const arena_;
// List of blocks in insertion order.
- GrowableArray<HBasicBlock*> blocks_;
+ ArenaVector<HBasicBlock*> blocks_;
// List of blocks to perform a reverse post order tree traversal.
- GrowableArray<HBasicBlock*> reverse_post_order_;
+ ArenaVector<HBasicBlock*> reverse_post_order_;
// List of blocks to perform a linear order tree traversal.
- GrowableArray<HBasicBlock*> linear_order_;
+ ArenaVector<HBasicBlock*> linear_order_;
HBasicBlock* entry_block_;
HBasicBlock* exit_block_;
HLoopInformation(HBasicBlock* header, HGraph* graph)
: header_(header),
suspend_check_(nullptr),
- back_edges_(graph->GetArena(), kDefaultNumberOfBackEdges),
+ back_edges_(graph->GetArena()->Adapter(kArenaAllocLoopInfoBackEdges)),
// Make bit vector growable, as the number of blocks may change.
- blocks_(graph->GetArena(), graph->GetBlocks().Size(), true) {}
+ blocks_(graph->GetArena(), graph->GetBlocks().size(), true) {
+ back_edges_.reserve(kDefaultNumberOfBackEdges);
+ }
HBasicBlock* GetHeader() const {
return header_;
bool HasSuspendCheck() const { return suspend_check_ != nullptr; }
void AddBackEdge(HBasicBlock* back_edge) {
- back_edges_.Add(back_edge);
+ back_edges_.push_back(back_edge);
}
void RemoveBackEdge(HBasicBlock* back_edge) {
- back_edges_.Delete(back_edge);
+ RemoveElement(back_edges_, back_edge);
}
bool IsBackEdge(const HBasicBlock& block) const {
- for (size_t i = 0, e = back_edges_.Size(); i < e; ++i) {
- if (back_edges_.Get(i) == &block) return true;
- }
- return false;
+ return ContainsElement(back_edges_, &block);
}
size_t NumberOfBackEdges() const {
- return back_edges_.Size();
+ return back_edges_.size();
}
HBasicBlock* GetPreHeader() const;
- const GrowableArray<HBasicBlock*>& GetBackEdges() const {
+ const ArenaVector<HBasicBlock*>& GetBackEdges() const {
return back_edges_;
}
size_t GetLifetimeEnd() const;
void ReplaceBackEdge(HBasicBlock* existing, HBasicBlock* new_back_edge) {
- for (size_t i = 0, e = back_edges_.Size(); i < e; ++i) {
- if (back_edges_.Get(i) == existing) {
- back_edges_.Put(i, new_back_edge);
- return;
- }
- }
- UNREACHABLE();
+ ReplaceElement(back_edges_, existing, new_back_edge);
}
// Finds blocks that are part of this loop. Returns whether the loop is a natural loop,
HBasicBlock* header_;
HSuspendCheck* suspend_check_;
- GrowableArray<HBasicBlock*> back_edges_;
+ ArenaVector<HBasicBlock*> back_edges_;
ArenaBitVector blocks_;
DISALLOW_COPY_AND_ASSIGN(HLoopInformation);
};
static constexpr size_t kNoLifetime = -1;
+static constexpr uint32_t kInvalidBlockId = static_cast<uint32_t>(-1);
// A block in a method. Contains the list of instructions represented
// as a double linked list. Each block knows its predecessors and
loop_information_(nullptr),
dominator_(nullptr),
dominated_blocks_(graph->GetArena()->Adapter(kArenaAllocDominated)),
- block_id_(-1),
+ block_id_(kInvalidBlockId),
dex_pc_(dex_pc),
lifetime_start_(kNoLifetime),
lifetime_end_(kNoLifetime),
HGraph* GetGraph() const { return graph_; }
void SetGraph(HGraph* graph) { graph_ = graph; }
- int GetBlockId() const { return block_id_; }
+ uint32_t GetBlockId() const { return block_id_; }
void SetBlockId(int id) { block_id_ = id; }
uint32_t GetDexPc() const { return dex_pc_; }
HLoopInformation* loop_information_;
HBasicBlock* dominator_;
ArenaVector<HBasicBlock*> dominated_blocks_;
- int block_id_;
+ uint32_t block_id_;
// The dex program counter of the first instruction of this block.
const uint32_t dex_pc_;
size_t lifetime_start_;
// instructions they use and pointers to the corresponding HUseListNodes kept
// by the used instructions.
template <typename T>
-class HUserRecord : public ValueObject {
+class HUserRecord {
public:
HUserRecord() : instruction_(nullptr), use_node_(nullptr) {}
explicit HUserRecord(HInstruction* instruction) : instruction_(instruction), use_node_(nullptr) {}
uint32_t dex_pc,
InvokeType invoke_type,
HInstruction* holder)
- : vregs_(arena, number_of_vregs),
- locations_(arena, number_of_vregs),
+ : vregs_(number_of_vregs, arena->Adapter(kArenaAllocEnvironmentVRegs)),
+ locations_(number_of_vregs, arena->Adapter(kArenaAllocEnvironmentLocations)),
parent_(nullptr),
dex_file_(dex_file),
method_idx_(method_idx),
dex_pc_(dex_pc),
invoke_type_(invoke_type),
holder_(holder) {
- vregs_.SetSize(number_of_vregs);
- for (size_t i = 0; i < number_of_vregs; i++) {
- vregs_.Put(i, HUserRecord<HEnvironment*>());
- }
-
- locations_.SetSize(number_of_vregs);
- for (size_t i = 0; i < number_of_vregs; ++i) {
- locations_.Put(i, Location());
- }
}
HEnvironment(ArenaAllocator* arena, const HEnvironment& to_copy, HInstruction* holder)
void CopyFromWithLoopPhiAdjustment(HEnvironment* env, HBasicBlock* loop_header);
void SetRawEnvAt(size_t index, HInstruction* instruction) {
- vregs_.Put(index, HUserRecord<HEnvironment*>(instruction));
+ DCHECK_LT(index, Size());
+ vregs_[index] = HUserRecord<HEnvironment*>(instruction);
}
HInstruction* GetInstructionAt(size_t index) const {
- return vregs_.Get(index).GetInstruction();
+ DCHECK_LT(index, Size());
+ return vregs_[index].GetInstruction();
}
void RemoveAsUserOfInput(size_t index) const;
- size_t Size() const { return vregs_.Size(); }
+ size_t Size() const { return vregs_.size(); }
HEnvironment* GetParent() const { return parent_; }
void SetLocationAt(size_t index, Location location) {
- locations_.Put(index, location);
+ DCHECK_LT(index, Size());
+ locations_[index] = location;
}
Location GetLocationAt(size_t index) const {
- return locations_.Get(index);
+ DCHECK_LT(index, Size());
+ return locations_[index];
}
uint32_t GetDexPc() const {
void RecordEnvUse(HUseListNode<HEnvironment*>* env_use) {
DCHECK(env_use->GetUser() == this);
size_t index = env_use->GetIndex();
- vregs_.Put(index, HUserRecord<HEnvironment*>(vregs_.Get(index), env_use));
+ DCHECK_LT(index, Size());
+ vregs_[index] = HUserRecord<HEnvironment*>(vregs_[index], env_use);
}
- GrowableArray<HUserRecord<HEnvironment*> > vregs_;
- GrowableArray<Location> locations_;
+ ArenaVector<HUserRecord<HEnvironment*>> vregs_;
+ ArenaVector<Location> locations_;
HEnvironment* parent_;
const DexFile& dex_file_;
const uint32_t method_idx_;
class HInvoke : public HInstruction {
public:
- size_t InputCount() const OVERRIDE { return inputs_.Size(); }
+ size_t InputCount() const OVERRIDE { return inputs_.size(); }
// Runtime needs to walk the stack, so Dex -> Dex calls need to
// know their environment.
: HInstruction(
SideEffects::AllExceptGCDependency(), dex_pc), // Assume write/read on all fields/arrays.
number_of_arguments_(number_of_arguments),
- inputs_(arena, number_of_arguments),
+ inputs_(number_of_arguments + number_of_other_inputs, arena->Adapter(kArenaAllocInvokeInputs)),
return_type_(return_type),
dex_method_index_(dex_method_index),
original_invoke_type_(original_invoke_type),
intrinsic_(Intrinsics::kNone),
needs_environment_or_cache_(kNeedsEnvironmentOrCache) {
- uint32_t number_of_inputs = number_of_arguments + number_of_other_inputs;
- inputs_.SetSize(number_of_inputs);
}
- const HUserRecord<HInstruction*> InputRecordAt(size_t i) const OVERRIDE { return inputs_.Get(i); }
+ const HUserRecord<HInstruction*> InputRecordAt(size_t index) const OVERRIDE {
+ DCHECK_LT(index, InputCount());
+ return inputs_[index];
+ }
+
void SetRawInputRecordAt(size_t index, const HUserRecord<HInstruction*>& input) OVERRIDE {
- inputs_.Put(index, input);
+ DCHECK_LT(index, InputCount());
+ inputs_[index] = input;
}
uint32_t number_of_arguments_;
- GrowableArray<HUserRecord<HInstruction*> > inputs_;
+ ArenaVector<HUserRecord<HInstruction*>> inputs_;
const Primitive::Type return_type_;
const uint32_t dex_method_index_;
const InvokeType original_invoke_type_;
DCHECK(last_input != nullptr);
DCHECK(last_input->IsLoadClass()) << last_input->DebugName();
RemoveAsUserOfInput(last_input_index);
- inputs_.DeleteAt(last_input_index);
+ inputs_.pop_back();
clinit_check_requirement_ = ClinitCheckRequirement::kImplicit;
DCHECK(IsStaticWithImplicitClinitCheck());
}
DCHECK(last_input != nullptr);
DCHECK(last_input->IsFakeString()) << last_input->DebugName();
RemoveAsUserOfInput(last_input_index);
- inputs_.DeleteAt(last_input_index);
+ inputs_.pop_back();
}
// Is this a call to a static method whose declaring class has an
Primitive::Type type,
uint32_t dex_pc = kNoDexPc)
: HInstruction(SideEffects::None(), dex_pc),
- inputs_(arena, number_of_inputs),
+ inputs_(number_of_inputs, arena->Adapter(kArenaAllocPhiInputs)),
reg_number_(reg_number),
type_(type),
is_live_(false),
can_be_null_(true) {
- inputs_.SetSize(number_of_inputs);
}
// Returns a type equivalent to the given `type`, but that a `HPhi` can hold.
bool IsCatchPhi() const { return GetBlock()->IsCatchBlock(); }
- size_t InputCount() const OVERRIDE { return inputs_.Size(); }
+ size_t InputCount() const OVERRIDE { return inputs_.size(); }
void AddInput(HInstruction* input);
void RemoveInputAt(size_t index);
DECLARE_INSTRUCTION(Phi);
protected:
- const HUserRecord<HInstruction*> InputRecordAt(size_t i) const OVERRIDE { return inputs_.Get(i); }
+ const HUserRecord<HInstruction*> InputRecordAt(size_t index) const OVERRIDE {
+ DCHECK_LE(index, InputCount());
+ return inputs_[index];
+ }
void SetRawInputRecordAt(size_t index, const HUserRecord<HInstruction*>& input) OVERRIDE {
- inputs_.Put(index, input);
+ DCHECK_LE(index, InputCount());
+ inputs_[index] = input;
}
private:
- GrowableArray<HUserRecord<HInstruction*> > inputs_;
+ ArenaVector<HUserRecord<HInstruction*> > inputs_;
const uint32_t reg_number_;
Primitive::Type type_;
bool is_live_;
public:
explicit HInsertionOrderIterator(const HGraph& graph) : graph_(graph), index_(0) {}
- bool Done() const { return index_ == graph_.GetBlocks().Size(); }
- HBasicBlock* Current() const { return graph_.GetBlocks().Get(index_); }
+ bool Done() const { return index_ == graph_.GetBlocks().size(); }
+ HBasicBlock* Current() const { return graph_.GetBlock(index_); }
void Advance() { ++index_; }
private:
public:
explicit HReversePostOrderIterator(const HGraph& graph) : graph_(graph), index_(0) {
// Check that reverse post order of the graph has been built.
- DCHECK(!graph.GetReversePostOrder().IsEmpty());
+ DCHECK(!graph.GetReversePostOrder().empty());
}
- bool Done() const { return index_ == graph_.GetReversePostOrder().Size(); }
- HBasicBlock* Current() const { return graph_.GetReversePostOrder().Get(index_); }
+ bool Done() const { return index_ == graph_.GetReversePostOrder().size(); }
+ HBasicBlock* Current() const { return graph_.GetReversePostOrder()[index_]; }
void Advance() { ++index_; }
private:
class HPostOrderIterator : public ValueObject {
public:
explicit HPostOrderIterator(const HGraph& graph)
- : graph_(graph), index_(graph_.GetReversePostOrder().Size()) {
+ : graph_(graph), index_(graph_.GetReversePostOrder().size()) {
// Check that reverse post order of the graph has been built.
- DCHECK(!graph.GetReversePostOrder().IsEmpty());
+ DCHECK(!graph.GetReversePostOrder().empty());
}
bool Done() const { return index_ == 0; }
- HBasicBlock* Current() const { return graph_.GetReversePostOrder().Get(index_ - 1); }
+ HBasicBlock* Current() const { return graph_.GetReversePostOrder()[index_ - 1u]; }
void Advance() { --index_; }
private:
class HLinearPostOrderIterator : public ValueObject {
public:
explicit HLinearPostOrderIterator(const HGraph& graph)
- : order_(graph.GetLinearOrder()), index_(graph.GetLinearOrder().Size()) {}
+ : order_(graph.GetLinearOrder()), index_(graph.GetLinearOrder().size()) {}
bool Done() const { return index_ == 0; }
- HBasicBlock* Current() const { return order_.Get(index_ -1); }
+ HBasicBlock* Current() const { return order_[index_ - 1u]; }
void Advance() {
--index_;
}
private:
- const GrowableArray<HBasicBlock*>& order_;
+ const ArenaVector<HBasicBlock*>& order_;
size_t index_;
DISALLOW_COPY_AND_ASSIGN(HLinearPostOrderIterator);
explicit HLinearOrderIterator(const HGraph& graph)
: order_(graph.GetLinearOrder()), index_(0) {}
- bool Done() const { return index_ == order_.Size(); }
- HBasicBlock* Current() const { return order_.Get(index_); }
+ bool Done() const { return index_ == order_.size(); }
+ HBasicBlock* Current() const { return order_[index_]; }
void Advance() { ++index_; }
private:
- const GrowableArray<HBasicBlock*>& order_;
+ const ArenaVector<HBasicBlock*>& order_;
size_t index_;
DISALLOW_COPY_AND_ASSIGN(HLinearOrderIterator);
}
}
- bool Done() const { return index_ == blocks_.Size(); }
- HBasicBlock* Current() const { return blocks_.Get(index_); }
+ bool Done() const { return index_ == blocks_.size(); }
+ HBasicBlock* Current() const { return blocks_[index_]; }
void Advance() {
++index_;
- for (size_t e = blocks_.Size(); index_ < e; ++index_) {
+ for (size_t e = blocks_.size(); index_ < e; ++index_) {
if (blocks_in_loop_.IsBitSet(index_)) {
break;
}
private:
const BitVector& blocks_in_loop_;
- const GrowableArray<HBasicBlock*>& blocks_;
+ const ArenaVector<HBasicBlock*>& blocks_;
size_t index_;
DISALLOW_COPY_AND_ASSIGN(HBlocksInLoopIterator);
: blocks_in_loop_(info.GetBlocks()),
blocks_(info.GetHeader()->GetGraph()->GetReversePostOrder()),
index_(0) {
- if (!blocks_in_loop_.IsBitSet(blocks_.Get(index_)->GetBlockId())) {
+ DCHECK(!blocks_.empty());
+ if (!blocks_in_loop_.IsBitSet(blocks_[index_]->GetBlockId())) {
Advance();
}
}
- bool Done() const { return index_ == blocks_.Size(); }
- HBasicBlock* Current() const { return blocks_.Get(index_); }
+ bool Done() const { return index_ == blocks_.size(); }
+ HBasicBlock* Current() const { return blocks_[index_]; }
void Advance() {
++index_;
- for (size_t e = blocks_.Size(); index_ < e; ++index_) {
- if (blocks_in_loop_.IsBitSet(blocks_.Get(index_)->GetBlockId())) {
+ for (size_t e = blocks_.size(); index_ < e; ++index_) {
+ if (blocks_in_loop_.IsBitSet(blocks_[index_]->GetBlockId())) {
break;
}
}
private:
const BitVector& blocks_in_loop_;
- const GrowableArray<HBasicBlock*>& blocks_;
+ const ArenaVector<HBasicBlock*>& blocks_;
size_t index_;
DISALLOW_COPY_AND_ASSIGN(HBlocksInLoopReversePostOrderIterator);
}
}
}
- GrowableArray<HBasicBlock*> blocks(&allocator, 0);
+ ArenaVector<HBasicBlock*> blocks(allocator.Adapter());
code_gen->block_order_ = &blocks;
code_gen->ComputeSpillMask();
code_gen->SetFrameSize(frame_size);
}
void RemoveSuspendChecks(HGraph* graph) {
- for (size_t i = 0, e = graph->GetBlocks().Size(); i < e; ++i) {
- for (HInstructionIterator it(graph->GetBlocks().Get(i)->GetInstructions());
- !it.Done();
- it.Advance()) {
+ for (HBasicBlock* block : graph->GetBlocks()) {
+ for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) {
HInstruction* current = it.Current();
if (current->IsSuspendCheck()) {
current->GetBlock()->RemoveInstruction(current);
register_allocator.AllocateRegisters();
ASSERT_TRUE(register_allocator.Validate(false));
- HBasicBlock* loop_header = graph->GetBlocks().Get(2);
+ HBasicBlock* loop_header = graph->GetBlock(2);
HPhi* phi = loop_header->GetFirstPhi()->AsPhi();
LiveInterval* phi_interval = phi->GetLiveInterval();
ASSERT_TRUE(loop_update->HasRegister());
ASSERT_NE(phi_interval->GetRegister(), loop_update->GetRegister());
- HBasicBlock* return_block = graph->GetBlocks().Get(3);
+ HBasicBlock* return_block = graph->GetBlock(3);
HReturn* ret = return_block->GetLastInstruction()->AsReturn();
ASSERT_EQ(phi_interval->GetRegister(), ret->InputAt(0)->GetLiveInterval()->GetRegister());
}
SsaLivenessAnalysis liveness(graph, &codegen);
liveness.Analyze();
- HXor* first_xor = graph->GetBlocks().Get(1)->GetFirstInstruction()->AsXor();
- HXor* last_xor = graph->GetBlocks().Get(1)->GetLastInstruction()->GetPrevious()->AsXor();
+ HXor* first_xor = graph->GetBlock(1)->GetFirstInstruction()->AsXor();
+ HXor* last_xor = graph->GetBlock(1)->GetLastInstruction()->GetPrevious()->AsXor();
ASSERT_EQ(last_xor->InputAt(0), first_xor);
LiveInterval* interval = first_xor->GetLiveInterval();
ASSERT_EQ(interval->GetEnd(), last_xor->GetLifetimePosition());
void SideEffectsAnalysis::Run() {
// Inlining might have created more blocks, so we need to increase the size
// if needed.
- block_effects_.SetSize(graph_->GetBlocks().Size());
- loop_effects_.SetSize(graph_->GetBlocks().Size());
+ block_effects_.SetSize(graph_->GetBlocks().size());
+ loop_effects_.SetSize(graph_->GetBlocks().size());
// In DEBUG mode, ensure side effects are properly initialized to empty.
if (kIsDebugBuild) {
explicit SideEffectsAnalysis(HGraph* graph)
: HOptimization(graph, kSideEffectsAnalysisPassName),
graph_(graph),
- block_effects_(graph->GetArena(), graph->GetBlocks().Size(), SideEffects::None()),
- loop_effects_(graph->GetArena(), graph->GetBlocks().Size(), SideEffects::None()) {}
+ block_effects_(graph->GetArena(), graph->GetBlocks().size(), SideEffects::None()),
+ loop_effects_(graph->GetArena(), graph->GetBlocks().size(), SideEffects::None()) {}
SideEffects GetLoopEffects(HBasicBlock* block) const;
SideEffects GetBlockEffects(HBasicBlock* block) const;
: HGraphVisitor(graph),
current_locals_(nullptr),
loop_headers_(graph->GetArena(), kDefaultNumberOfLoops),
- locals_for_(graph->GetArena(), graph->GetBlocks().Size()) {
- locals_for_.SetSize(graph->GetBlocks().Size());
+ locals_for_(graph->GetArena(), graph->GetBlocks().size()) {
+ locals_for_.SetSize(graph->GetBlocks().size());
}
void BuildSsa();
// current reverse post order in the graph, but it would require making
// order queries to a GrowableArray, which is not the best data structure
// for it.
- GrowableArray<uint32_t> forward_predecessors(graph_->GetArena(), graph_->GetBlocks().Size());
- forward_predecessors.SetSize(graph_->GetBlocks().Size());
+ GrowableArray<uint32_t> forward_predecessors(graph_->GetArena(), graph_->GetBlocks().size());
+ forward_predecessors.SetSize(graph_->GetBlocks().size());
for (HReversePostOrderIterator it(*graph_); !it.Done(); it.Advance()) {
HBasicBlock* block = it.Current();
size_t number_of_forward_predecessors = block->GetPredecessors().size();
// iterate over the successors. When all non-back edge predecessors of a
// successor block are visited, the successor block is added in the worklist
// following an order that satisfies the requirements to build our linear graph.
+ graph_->linear_order_.reserve(graph_->GetReversePostOrder().size());
GrowableArray<HBasicBlock*> worklist(graph_->GetArena(), 1);
worklist.Add(graph_->GetEntryBlock());
do {
HBasicBlock* current = worklist.Pop();
- graph_->linear_order_.Add(current);
+ graph_->linear_order_.push_back(current);
for (HBasicBlock* successor : current->GetSuccessors()) {
int block_id = successor->GetBlockId();
size_t number_of_remaining_predecessors = forward_predecessors.Get(block_id);
SsaLivenessAnalysis(HGraph* graph, CodeGenerator* codegen)
: graph_(graph),
codegen_(codegen),
- block_infos_(graph->GetArena(), graph->GetBlocks().Size()),
+ block_infos_(graph->GetArena(), graph->GetBlocks().size()),
instructions_from_ssa_index_(graph->GetArena(), 0),
instructions_from_lifetime_position_(graph->GetArena(), 0),
number_of_ssa_values_(0) {
- block_infos_.SetSize(graph->GetBlocks().Size());
+ block_infos_.SetSize(graph->GetBlocks().size());
}
void Analyze();
static void ReNumberInstructions(HGraph* graph) {
int id = 0;
- for (size_t i = 0, e = graph->GetBlocks().Size(); i < e; ++i) {
- HBasicBlock* block = graph->GetBlocks().Get(i);
+ for (HBasicBlock* block : graph->GetBlocks()) {
for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) {
it.Current()->SetId(id++);
}
ReNumberInstructions(graph);
// Test that phis had their type set.
- for (size_t i = 0, e = graph->GetBlocks().Size(); i < e; ++i) {
- for (HInstructionIterator it(graph->GetBlocks().Get(i)->GetPhis()); !it.Done(); it.Advance()) {
+ for (HBasicBlock* block : graph->GetBlocks()) {
+ for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) {
ASSERT_NE(it.Current()->GetType(), Primitive::kPrimVoid);
}
}
"STL ",
"Graph ",
"BasicBlock ",
+ "BlockList ",
+ "RevPostOrder ",
+ "LinearOrder ",
+ "ConstantsMap ",
"Predecessors ",
"Successors ",
"Dominated ",
"Instruction ",
+ "InvokeInputs ",
+ "PhiInputs ",
"LoopInfo ",
+ "LIBackEdges ",
"TryCatchInf ",
"UseListNode ",
"Environment ",
+ "EnvVRegs ",
+ "EnvLocations ",
"MoveOperands ",
"CodeBuffer ",
"StackMaps ",
kArenaAllocSTL,
kArenaAllocGraph,
kArenaAllocBasicBlock,
+ kArenaAllocBlockList,
+ kArenaAllocReversePostOrder,
+ kArenaAllocLinearOrder,
+ kArenaAllocConstantsMap,
kArenaAllocPredecessors,
kArenaAllocSuccessors,
kArenaAllocDominated,
kArenaAllocInstruction,
+ kArenaAllocInvokeInputs,
+ kArenaAllocPhiInputs,
kArenaAllocLoopInfo,
+ kArenaAllocLoopInfoBackEdges,
kArenaAllocTryCatchInfo,
kArenaAllocUseListNode,
kArenaAllocEnvironment,
+ kArenaAllocEnvironmentVRegs,
+ kArenaAllocEnvironmentLocations,
kArenaAllocMoveOperands,
kArenaAllocCodeBuffer,
kArenaAllocStackMaps,