The CFIFixup pass assumes a function prologue is contained in a single basic
block. This assumption is broken with upcoming support for stack probing
(-fstack-clash-protection
) in AArch64 [1] - the emitted probing sequence in a
prologue may contain loops, i.e. more than one basic block. The generated CFG is
not arbitrary though, in the end the prologue forms a single
single-entry/single-exit region.
I’ve considered a few approaches to handle this in CFIFixup:
-
Find the block that (a) contains instructions with the flag
FrameSetup
and
(b) post-dominates every other block that contains instructions with the
flagFrameSetup
.- pros: that is fairly universal, with changes confined to the CFIFixup pass alone
- cons: a bit on the heavy side, requires construction of the Machine PostDominator tree.
-
Add a new
MachineInstr
flag (sayMachineInstr::PrologueEnd
) and mark the
first instruction after the prologue- pros: super cheap, just a one extra bit
- cons: transformations (e.g. reversing condition on branch instructions) may not
preserve MI flags
-
Add a new operation code (say
OpPrologueEnd
) toMCCFIInstruction
and emit
aCFI_INSTRUCTION
.- pros: nothing in particular
- cons: does not seem entirely inline with the design and intent of
MCCFIInstruction
, since there won’t be a corresponding.cfi_...
directive and may break users ofMCCFIInstruction
who expect to handle every opcode (e.g. in a switch statement) and assert on unrecognised opcode.
-
Add a new target independent pseudo-, meta- instruction, say
TargetOpcode::PROLOGUE_END
.- pros: This is similar to what Windows for AArch64 does (
AArch64::SEH_PrologEnd
), except that forCodeGen/CFIFixup.cpp
we need a target independent one. - cons: nothing in partilcular
This is my preferred approach right now.
- pros: This is similar to what Windows for AArch64 does (
Are there any other ideas?