This is an archive of the discontinued LLVM Phabricator instance.

[ScopBuilder]Fix bug 38358 by preserve correct order of ScopStmts
ClosedPublic

Authored by bin.narwal on Oct 14 2019, 5:17 AM.

Details

Summary

Hi,
ScopBuilder::buildEqivClassBlockStmts creates ScopStmts for instruction groups in basic block and inserts these ScopStmts into Scop::StmtMap, however, as described in https://bugs.llvm.org/show_bug.cgi?id=38358, comment #5, StmtScops are inserted into vector ScopStmt[BB] in wrong order. As a result, ScopBuilder::buildSchedule creates wrong order sequence node.

Looking closer to code, it's clear there is no equivalent classes with interleaving isOrderedInstruction(memory access) instructions after joinOrderedInstructions. Afterwards, ScopStmts need to be created and inserted in the original order of memory access instructions, however, at the moment ScopStmts are inserted in the order of leader instructions which are probably not memory access instructions.

The fix is simple with a standalone loop scanning isOrderedInstruction(memory access) instructions in basic block and inserting elements into LeaderToInstList one by one. The patch also removes double reversing operations which are now unnecessary.

New test preserve-equiv-class-order-in-basic_block.ll is also added. Comments?

Thanks,
bin

Diff Detail

Event Timeline

bin.narwal created this revision.Oct 14 2019, 5:17 AM

I remember I cared about the epilogue being the last, which is the reason for the reversed list. It ensures that the terminator is always visited first, hence added first into the list, hence being the last statement. (I am a bit surprised that no test fails). An example could be:

%b = load %B  // merged with terminator by joinOperandTree
store 42 // independent statement
br %b // terminator, epilogue

Seeing this example, it is clear that load %B (and therefore the epilogue) cannot be put after store 42, as it might store to %A. That is, the epilogue is not necessarily always the last instruction. It should not matter since the PHI-writes have their own memory locations that do not alias with other memory.
[^^ just my thoughts about whether everything is sound; I could not find an issue]

Looks correct, Thanks for the patch!
Do you want me to commit this for you?

lib/Analysis/ScopBuilder.cpp
2125–2126 ↗(On Diff #224832)

[grammar/suggestion] The order of statements must be preserved w.r.t. their ordered instructions. Without this explicit scan, we would also use non-ordered instructions (whose order is arbitrary) to determine statement order.

2137 ↗(On Diff #224832)

[typo] elment

test/ScopInfo/preserve-equiv-class-order-in-basic_block.ll
66–68 ↗(On Diff #224832)

[suggestion] Can you try to reduce unnecessary parts? Such as: function attributes, instruction attributes ("!tbba"), comdat, module metadata (!llvm.module.flags, !llvm.ident). Function parameters are nicer than globals, but more work to convert.

Meinersbur accepted this revision.Oct 14 2019, 4:59 PM
This revision is now accepted and ready to land.Oct 14 2019, 4:59 PM
bin.narwal marked 3 inline comments as done.

Fixed as you suggested. Yes please help commit this on behalf of me.

Thanks,
bin

I remember I cared about the epilogue being the last, which is the reason for the reversed list. It ensures that the terminator is always visited first, hence added first into the list, hence being the last statement. (I am a bit surprised that no test fails). An example could be:

%b = load %B  // merged with terminator by joinOperandTree
store 42 // independent statement
br %b // terminator, epilogue

Seeing this example, it is clear that load %B (and therefore the epilogue) cannot be put after store 42, as it might store to %A. That is, the epilogue is not necessarily always the last instruction. It should not matter since the PHI-writes have their own memory locations that do not alias with other memory.
[^^ just my thoughts about whether everything is sound; I could not find an issue]

That's because the code doesn't model branch instruction (which is terminator) at all right now. If in case terminator instruction must be handled, we would need to handle it as an "ordered" instruction, just like memory access ones.

Looks correct, Thanks for the patch!
Do you want me to commit this for you?

Yes, please.

Thanks,
bin

This revision was automatically updated to reflect the committed changes.

Thanks for that patch!

Unfortunately I forgot the "Patch by" line. Please excuse the neglectfulness.

Thanks for that patch!

Unfortunately I forgot the "Patch by" line. Please excuse the neglectfulness.

That's all right. Thank you very much for help!