This is an archive of the discontinued LLVM Phabricator instance.

Refactor AtomicExpandPass and add a generic isAtomic() method to Instruction
ClosedPublic

Authored by morisset on Aug 22 2014, 5:42 PM.

Details

Summary

Split shouldExpandAtomicInIR() into different versions for Stores/Loads/RMWs/CmpXchgs.
Makes runOnFunction cleaner (no more redundant checking/casting), and will help moving
the X86 backend to this pass.

This requires a way of easily detecting which instructions are atomic.
I followed the pattern of mayReadFromMemory, mayWriteOrReadMemory, etc.. in making
isAtomic() a method of Instruction implemented by a switch on the opcodes.

Depends on D4960.

Diff Detail

Repository
rL LLVM

Event Timeline

morisset updated this revision to Diff 12870.Aug 22 2014, 5:42 PM
morisset retitled this revision from to Refactor AtomicExpandPass and add a generic isAtomic() method to Instruction.
morisset updated this object.
morisset edited the test plan for this revision. (Show Details)
morisset added a reviewer: jfb.
morisset added a subscriber: Unknown Object (MLST).
jfb added inline comments.Aug 24 2014, 2:34 PM
include/llvm/IR/Instruction.h
338 ↗(On Diff #12870)

Comments tend to go out of sync with the code, so I wouldn't state anything here on which instructions can be atomic.

include/llvm/Target/TargetLowering.h
981 ↗(On Diff #12870)

Comma at the end?

983 ↗(On Diff #12870)

You'll probably need to send a PSA to the mailing list to explain the change you're making, and the impact on any out-of-tree implementation of this class (removing one virtual method, and adding some).

989 ↗(On Diff #12870)

Period at the end (same for other comments).

996 ↗(On Diff #12870)

Document when CmpXchg or LL/SC are used.

1000 ↗(On Diff #12870)

Why no shouldExpandAtomicCmpXchgInIR?

lib/CodeGen/AtomicExpandPass.cpp
91 ↗(On Diff #12870)

You should probably keep this else clause, in case isAtomic goes out of sync with this code (just have a do-nothing clause for Fence).

373 ↗(On Diff #12870)

Drop this line change.

lib/Target/ARM/ARMISelLowering.cpp
11065 ↗(On Diff #12870)

I'm not sure that's quite correct on CortexA: Thumb only has ldrex/strex on ARMv7, and ARM has them on ARMv6K and ARMv7.

A further enhancement (doesn't affect correctness): processors can also use ldrd/strd atomically when HaveLPAE is true. On ARM's own processors this requires A15 (I'm not sure about other vendors).

Patch coming just afterwards, I just answer to a few of the inline comments.

include/llvm/Target/TargetLowering.h
996 ↗(On Diff #12870)

This comment is a mistake on my part, currently LL/SC is always used, support for using CmpXchg is coming in the next patch.

1000 ↗(On Diff #12870)

Because they should always be expanded when the target supports ll/sc and never when it supports CAS natively. I do not know of any target offering both ll/sc and cas.

The current code assumes that the target has LL/SC, this assumption is removed in another patch that I am hoping to send soon, that makes the X86 backend use this pass. This other patch will add a hasLoadLinkedStoreConditional() target hook which will both decide whether to expand CmpXchgs, and how to expand RMWs.

lib/CodeGen/AtomicExpandPass.cpp
91 ↗(On Diff #12870)

Because these conditions also test the shouldExpand*, I cannot leave the llvm_unreachable. Instead I will add an assert.

lib/Target/ARM/ARMISelLowering.cpp
11065 ↗(On Diff #12870)

I merely kept the current behaviour and explanation. Is it ok to keep it as-is for now, and look at improving this in a later patch?

morisset updated this revision to Diff 12910.Aug 25 2014, 12:44 PM

Fix things pointed out by jfb.

See comments inline sent previously for details.

jfb accepted this revision.Aug 25 2014, 1:17 PM
jfb edited edge metadata.

This lgtm with one comment to add, and a follow-up patch for ldrex/strex.

I think you should send the PSA about shouldExpandAtomicInIR before committing.

include/llvm/Target/TargetLowering.h
1000 ↗(On Diff #12870)

Could you add a temporary comment explaining this (and remove it in the next patch)? It'll make it easier for people looking at diff history to understand how the code evolved (instead of having to go to the review).

lib/Target/ARM/ARMISelLowering.cpp
11065 ↗(On Diff #12870)

Agreed that your change is keeping the same behavior. Agreed you can fix & improve in a separate patch.

This revision is now accepted and ready to land.Aug 25 2014, 1:17 PM
morisset updated this object.Aug 27 2014, 3:05 PM
morisset edited edge metadata.
morisset updated this revision to Diff 13010.Aug 27 2014, 4:00 PM

Fix formatting with clang-format.

jfb added inline comments.Aug 27 2014, 4:06 PM
lib/CodeGen/AtomicExpandPass.cpp
150 ↗(On Diff #13010)

Something got messed up here and below.

morisset updated this revision to Diff 13012.Aug 27 2014, 4:15 PM

Fix formatting, curiously messed up by clang-format.

morisset closed this revision.Sep 3 2014, 2:39 PM
morisset updated this revision to Diff 13225.

Closed by commit rL217080 (authored by @morisset).