[SSP] Simplifying SSP code paths

I’m still working on SSP support in LLVM. We have code that is in an IR pass StackProtector, SelectionDAG, FastISel, and some MachineFunction passes. Even in SelectiondDAG we have different code paths. I wonder if we can at least have only two code paths, one for SelectionDAG and the other for FastISel.

IR pass may generate two forms of IR:1) Almost pure IR, which contains only llvm.stackprotector that can be lowered.
2) An IR skeleton which contains llvm.stackprotector and llvm.stackprotectorcheck.

FastISel only needs to look at 1). However, if FastISel fails to lower it (which is certainly possible), it falls back to SelectionDAG. SelectionDAG must handle 1) form. SelectionDAG must handle 2) form, since it’s only for SelectionDAG.

Conclusion 1: if FastISel is able to fallback to SelectionDAG, SelectionDAG must handle two different forms, potentially using two code paths.

Since we want to cut down either code path in SelectionDAG, we need to either not allow FastISel to fallback (which is nearly impossible), or IR pass must generate only one form, regardless it’s FastISel or not. Let’s say we take the latter.

Since SelectionDAG has only one code path, we must not put too much into the generated IR, because those IR must not get lowered in SelectionDAG SelectBasicBlock() (but in FinishBasicBlock() instead), due to tail call optimization concern.

Conclusion 2: if we want to keep both tail call optimization and single code path in SelectionDAG, we need to generate trivial IR (declarations for global variables and alloca of canary variable).

Promising Solution: Generating trivial IR, and let each of FastISel and SelectionDAG has one code path. SelectionDAG signals FastISel to handle SSP in SelectionAllBasicBlock(). If FastISel fails to handle that, it fallbacks to full SelectionDAG approach.

Seems perfect? My current concern is, I don’t know how to handle branch weight in FastISel. See:
https://github.com/llvm-mirror/llvm/blob/master/lib/CodeGen/StackProtector.cpp#L461. If we can’t handle branch weight in FastISel, it’s likely a performance regression.