I am working on writing a backend in LLVM and I am having a little trouble completely understanding chains. As far as I can tell, chains are used to represent dependencies that can’t be expressed by the typical def-use dependency. But I am uncertain where and how I should be using chains.
In the Code Generator documentation, they describe that chains should be used with instructions that have side effects loads, stores, calls, etc. I guess I am confused to as why those instructions need chains. For example, won’t loads have a dependency on address to ensure they are only scheduled after address generation. And stores will have dependencies and addresses and results to ensure they only occur after those values are created. Is it because of memory disambiguation causing us to be conservative and needing to ensure that certain store/loads aren’t re-ordered respect to each other?
I guess the real question is when I include chains for operations and when I want to return chains from operations (especially intrinsics). For example, with the backend, when I am inserting Loads from the stacks, I don’t want to chain them all together for performance, right, since it doesn’t matter when the loads are scheduled (as long as it is before the use). But I should chain them to the incoming chain from LowerFormalArguments parameter.
On somewhat related note, take this example DAG https://i.stack.imgur.com/RQRpq.gif, why does copyfromreg need a chain input?