Skip to content
This repository was archived by the owner on Sep 2, 2018. It is now read-only.

Support atomic operations #197

Closed
shepmaster opened this issue May 15, 2016 · 2 comments
Closed

Support atomic operations #197

shepmaster opened this issue May 15, 2016 · 2 comments
Assignees

Comments

@shepmaster
Copy link

Continuing to chug through compiling the Rust core library, I finally hit on atomics. LLVM has these ISDs defined:

ATOMIC_LOAD
ATOMIC_STORE

ATOMIC_CMP_SWAP
ATOMIC_CMP_SWAP_WITH_SUCCESS
ATOMIC_FENCE
ATOMIC_LOAD_ADD
ATOMIC_LOAD_AND
ATOMIC_LOAD_MAX
ATOMIC_LOAD_MIN
ATOMIC_LOAD_NAND
ATOMIC_LOAD_OR
ATOMIC_LOAD_SUB
ATOMIC_LOAD_UMAX
ATOMIC_LOAD_UMIN
ATOMIC_LOAD_XOR
ATOMIC_SWAP

Conceptually, it's "easy" to implement atomic access. Since there's only one core, the only thing we have to watch out for is an interrupt occurring. That means we can have pseudocode like this:

old_sreg = load SREG
cli
// Run interesting code here
SREG = old_sreg

I'd like to take a crack at this, but without having to re-implement the automatically-generated code for "load 32-bit values" and so on. Do you know if there's a way to wrap existing LLVM generated code in some extra code?

Do you see any overall bad ideas in this?

@dylanmckay
Copy link
Member

I believe you should be able to write a custom lowering hook (in AVRISelLowering.cpp call setOperationAction(..., ..., Custom). I wasn't sure if the legalizer tries to lower any illegal values after custom hooks run, but it looks like they must (see AVRISelLowering.cpp:around line 530).

In this function, we are returning nodes in the custom lowering function which are illegal (ISD::EXTRACT_ELEMENT & co). Therefore this would only work if LLVM tries to lower all illegal results from the hook.

You should be able to write a custom hook which creates a cli, one of the ISDNode copy/move nodes, and a sei node. LLVM should then lower the new ISDNode for you. It is definitely worth checking that.

Also, I'm not sure how much LLVM you've played with, but at this level in the pipeline, there is no guarantee your nodes will stay in the same order. I haven't dealt much with this, but LLVM has the concept of glue which sticks two nodes together, so they can't be separated.

Here is an example I found. This should glue the TST and the EXTRACT_ELEMENT nodes together.

SDValue Top = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, LHS3,
                         DAG.getIntPtrConstant(1, DL));
Cmp = DAG.getNode(AVRISD::TST, DL, MVT::Glue, Top);

@dylanmckay dylanmckay self-assigned this Jun 2, 2016
@dylanmckay
Copy link
Member

Have picked up work on this from @shepmaster, he got pretty far but got bogged down my LLVM internals :)

Almost got this working. It looks like we can only lower stuff in these hooks to nodes that are defined in ISDNodes or AVRISDNodes. Will need to add a new node for bclr (clear bit from SREG).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants