Commit 39fa51d4 authored by danno@chromium.org's avatar danno@chromium.org

Improve --trace-gvn debug output

R=mstarzinger@chromium.org

Review URL: https://chromiumcodereview.appspot.com/10203010

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11433 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 13c4191d
...@@ -1552,14 +1552,97 @@ void HGlobalValueNumberer::ComputeBlockSideEffects() { ...@@ -1552,14 +1552,97 @@ void HGlobalValueNumberer::ComputeBlockSideEffects() {
} }
SmartArrayPointer<char> GetGVNFlagsString(GVNFlagSet flags) {
#if DEBUG
char buffer[kLastFlag * 128];
const char* separator = "";
const char* comma = ", ";
buffer[0] = 0;
uint32_t set_depends_on = 0;
uint32_t set_changes = 0;
for (int bit = 0; bit < kLastFlag; ++bit) {
if ((flags.ToIntegral() & (1 << bit)) != 0) {
if (bit % 2 == 0) {
set_changes++;
} else {
set_depends_on++;
}
}
}
bool positive_changes = set_changes < (kLastFlag / 2);
bool positive_depends_on = set_depends_on < (kLastFlag / 2);
if (set_changes > 0) {
if (positive_changes) {
strcat(buffer, "changes [");
} else {
strcat(buffer, "changes all except [");
}
for (int bit = 0; bit < kLastFlag; ++bit) {
if (((flags.ToIntegral() & (1 << bit)) != 0) == positive_changes) {
switch (static_cast<GVNFlag>(bit)) {
#define DECLARE_FLAG(type) \
case kChanges##type: \
strcat(buffer, separator); \
strcat(buffer, #type); \
separator = comma; \
break;
GVN_TRACKED_FLAG_LIST(DECLARE_FLAG)
GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
#undef DECLARE_FLAG
default:
break;
}
}
}
strcat(buffer, "]");
}
if (set_depends_on > 0) {
separator = "";
if (set_changes > 0) {
strcat(buffer, ", ");
}
if (positive_depends_on) {
strcat(buffer, "depends on [");
} else {
strcat(buffer, "depends on all except [");
}
for (int bit = 0; bit < kLastFlag; ++bit) {
if (((flags.ToIntegral() & (1 << bit)) != 0) == positive_depends_on) {
switch (static_cast<GVNFlag>(bit)) {
#define DECLARE_FLAG(type) \
case kDependsOn##type: \
strcat(buffer, separator); \
strcat(buffer, #type); \
separator = comma; \
break;
GVN_TRACKED_FLAG_LIST(DECLARE_FLAG)
GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
#undef DECLARE_FLAG
default:
break;
}
}
}
strcat(buffer, "]");
}
#else
char buffer[128];
snprintf(buffer, 128, "0x%08X", flags.ToIntegral());
#endif
char* result = new char[strlen(buffer) + 1];
strcpy(result, buffer);
return SmartArrayPointer<char>(result);
}
void HGlobalValueNumberer::LoopInvariantCodeMotion() { void HGlobalValueNumberer::LoopInvariantCodeMotion() {
for (int i = graph_->blocks()->length() - 1; i >= 0; --i) { for (int i = graph_->blocks()->length() - 1; i >= 0; --i) {
HBasicBlock* block = graph_->blocks()->at(i); HBasicBlock* block = graph_->blocks()->at(i);
if (block->IsLoopHeader()) { if (block->IsLoopHeader()) {
GVNFlagSet side_effects = loop_side_effects_[block->block_id()]; GVNFlagSet side_effects = loop_side_effects_[block->block_id()];
TraceGVN("Try loop invariant motion for block B%d effects=0x%x\n", TraceGVN("Try loop invariant motion for block B%d %s\n",
block->block_id(), block->block_id(),
side_effects.ToIntegral()); *GetGVNFlagsString(side_effects));
GVNFlagSet accumulated_first_time_depends; GVNFlagSet accumulated_first_time_depends;
GVNFlagSet accumulated_first_time_changes; GVNFlagSet accumulated_first_time_changes;
...@@ -1582,20 +1665,19 @@ void HGlobalValueNumberer::ProcessLoopBlock( ...@@ -1582,20 +1665,19 @@ void HGlobalValueNumberer::ProcessLoopBlock(
GVNFlagSet* first_time_changes) { GVNFlagSet* first_time_changes) {
HBasicBlock* pre_header = loop_header->predecessors()->at(0); HBasicBlock* pre_header = loop_header->predecessors()->at(0);
GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(loop_kills); GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(loop_kills);
TraceGVN("Loop invariant motion for B%d depends_flags=0x%x\n", TraceGVN("Loop invariant motion for B%d %s\n",
block->block_id(), block->block_id(),
depends_flags.ToIntegral()); *GetGVNFlagsString(depends_flags));
HInstruction* instr = block->first(); HInstruction* instr = block->first();
while (instr != NULL) { while (instr != NULL) {
HInstruction* next = instr->next(); HInstruction* next = instr->next();
bool hoisted = false; bool hoisted = false;
if (instr->CheckFlag(HValue::kUseGVN)) { if (instr->CheckFlag(HValue::kUseGVN)) {
TraceGVN("Checking instruction %d (%s) instruction GVN flags 0x%X, " TraceGVN("Checking instruction %d (%s) %s. Loop %s\n",
"loop kills 0x%X\n",
instr->id(), instr->id(),
instr->Mnemonic(), instr->Mnemonic(),
instr->gvn_flags().ToIntegral(), *GetGVNFlagsString(instr->gvn_flags()),
depends_flags.ToIntegral()); *GetGVNFlagsString(loop_kills));
bool can_hoist = !instr->gvn_flags().ContainsAnyOf(depends_flags); bool can_hoist = !instr->gvn_flags().ContainsAnyOf(depends_flags);
if (instr->IsTransitionElementsKind()) { if (instr->IsTransitionElementsKind()) {
// It's possible to hoist transitions out of a loop as long as the // It's possible to hoist transitions out of a loop as long as the
...@@ -1619,14 +1701,14 @@ void HGlobalValueNumberer::ProcessLoopBlock( ...@@ -1619,14 +1701,14 @@ void HGlobalValueNumberer::ProcessLoopBlock(
hoist_change_blockers.Add(kChangesArrayElements); hoist_change_blockers.Add(kChangesArrayElements);
} }
TraceGVN("Checking dependencies on HTransitionElementsKind %d (%s) " TraceGVN("Checking dependencies on HTransitionElementsKind %d (%s) "
"hoist depends blockers 0x%X, hoist change blockers 0x%X, " "hoist blockers: %s %s; "
"accumulated depends 0x%X, accumulated changes 0x%X\n", "first-time accumulated: %s %s\n",
instr->id(), instr->id(),
instr->Mnemonic(), instr->Mnemonic(),
hoist_depends_blockers.ToIntegral(), *GetGVNFlagsString(hoist_depends_blockers),
hoist_change_blockers.ToIntegral(), *GetGVNFlagsString(hoist_change_blockers),
first_time_depends->ToIntegral(), *GetGVNFlagsString(*first_time_depends),
first_time_changes->ToIntegral()); *GetGVNFlagsString(*first_time_changes));
// It's possible to hoist transition from the current loop loop only if // It's possible to hoist transition from the current loop loop only if
// they dominate all of the successor blocks in the same loop and there // they dominate all of the successor blocks in the same loop and there
// are not any instructions that have Changes/DependsOn that intervene // are not any instructions that have Changes/DependsOn that intervene
...@@ -1661,8 +1743,18 @@ void HGlobalValueNumberer::ProcessLoopBlock( ...@@ -1661,8 +1743,18 @@ void HGlobalValueNumberer::ProcessLoopBlock(
if (!hoisted) { if (!hoisted) {
// If an instruction is not hoisted, we have to account for its side // If an instruction is not hoisted, we have to account for its side
// effects when hoisting later HTransitionElementsKind instructions. // effects when hoisting later HTransitionElementsKind instructions.
GVNFlagSet previous_depends = *first_time_depends;
GVNFlagSet previous_changes = *first_time_changes;
first_time_depends->Add(instr->DependsOnFlags()); first_time_depends->Add(instr->DependsOnFlags());
first_time_changes->Add(instr->ChangesFlags()); first_time_changes->Add(instr->ChangesFlags());
if (!(previous_depends == *first_time_depends)) {
TraceGVN("Updated first-time accumulated %s\n",
*GetGVNFlagsString(*first_time_depends));
}
if (!(previous_changes == *first_time_changes)) {
TraceGVN("Updated first-time accumulated %s\n",
*GetGVNFlagsString(*first_time_changes));
}
} }
instr = next; instr = next;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment