summaryrefslogtreecommitdiff
path: root/compiler/optimizing/nodes.cc
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2021-01-05 16:57:30 +0000
committer Vladimir Marko <vmarko@google.com> 2021-01-06 15:06:24 +0000
commitc9fcfd02a69170cedcd4cf2e66826f246dff6267 (patch)
tree2bc39091ec4dbc71bad37efafde41d13d168f0ca /compiler/optimizing/nodes.cc
parent782fb716122d37dc4c4d7482afb21f6e68be04b4 (diff)
Optimizing: Add debugging output for HInstruction.
Allow printing individual instruction and its arguments with the HGraphVisualizer. Arguments are dumped "recursively" (but implemented with a queue instead of actual recursion). For example, printing the Return instruction from the method Main.testLoop17 in 530-checker-lse yields v28 Return [i27] dex_pc:23 loop:none i27 Add [i24,i26] dex_pc:22 loop:none i24 Phi [i5,i15] dex_pc:n/a reg:0 is_catch_phi:false loop:none i5 IntConstant dex_pc:0 1 loop:none i15 IntConstant dex_pc:5 2 loop:none i26 InstanceFieldGet [l6] dex_pc:20 field_name:TestClass.i field_type:Int32 loop:none l6 NullCheck [l1] dex_pc:1 env:[[i5,_,_,l1,i2]] loop:none l1 ParameterValue dex_pc:n/a loop:none Test: Manual; modify LSE to print the instruction above. Change-Id: Iaf41ba62cd6a5a36236ad0abca082ebffcf6a20e
Diffstat (limited to 'compiler/optimizing/nodes.cc')
-rw-r--r--compiler/optimizing/nodes.cc38
1 files changed, 38 insertions, 0 deletions
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index e3e4589b63..d57eaf0b60 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -1312,6 +1312,44 @@ void HEnvironment::ReplaceInput(HInstruction* replacement, size_t index) {
orig_instr->FixUpUserRecordsAfterEnvUseRemoval(before_use_node);
}
+std::ostream& HInstruction::Dump(std::ostream& os, bool dump_args) {
+ HGraph* graph = GetBlock()->GetGraph();
+ HGraphVisualizer::DumpInstruction(&os, graph, this);
+ if (dump_args) {
+ // Allocate memory from local ScopedArenaAllocator.
+ ScopedArenaAllocator allocator(graph->GetArenaStack());
+ // Instructions that we already visited. We print each instruction only once.
+ ArenaBitVector visited(
+ &allocator, graph->GetCurrentInstructionId(), /* expandable= */ false, kArenaAllocMisc);
+ visited.ClearAllBits();
+ visited.SetBit(GetId());
+ // Keep a queue of instructions with their indentations.
+ ScopedArenaDeque<std::pair<HInstruction*, size_t>> queue(allocator.Adapter(kArenaAllocMisc));
+ auto add_args = [&queue](HInstruction* instruction, size_t indentation) {
+ for (HInstruction* arg : ReverseRange(instruction->GetInputs())) {
+ queue.emplace_front(arg, indentation);
+ }
+ };
+ add_args(this, /*indentation=*/ 1u);
+ while (!queue.empty()) {
+ HInstruction* instruction;
+ size_t indentation;
+ std::tie(instruction, indentation) = queue.front();
+ queue.pop_front();
+ if (!visited.IsBitSet(instruction->GetId())) {
+ visited.SetBit(instruction->GetId());
+ os << '\n';
+ for (size_t i = 0; i != indentation; ++i) {
+ os << " ";
+ }
+ HGraphVisualizer::DumpInstruction(&os, graph, instruction);
+ add_args(instruction, indentation + 1u);
+ }
+ }
+ }
+ return os;
+}
+
HInstruction* HInstruction::GetNextDisregardingMoves() const {
HInstruction* next = GetNext();
while (next != nullptr && next->IsParallelMove()) {