Skip to content

Commit e77489d

Browse files
committed
[CFIFixup] Fixup CFI for split functions with synchronous uwtables
Commit 6e54fcc disables CFI fixup for functions with synchronous tables, breaking CFI for split functions. Instead, we can disable *block-level* CFI fixup for functions with synchronous tables. Unwind tables can be: - N/A (not present) - Asynchronous - Synchronous Functions without unwind tables don't need CFI fixup (since they don't care about CFI). Functions with asynchronous unwind tables must be accurate for each basic block, so full CFI fixup is necessary. Functions with synchronous unwind tables only need to be accurate for each function (specifically, the portion of a function in a given section). Disabling CFI fixup entirely for functions with synchronous uwtables may break CFI for a function split between two sections. The portion in the first section may have valid CFI, while the portion in the second section is missing a call frame. Ex: ``` (.text.hot) Foo (BB1): <Call frame information> ... BB2: ... (.text.split) BB3: ... BB4: <epilogue> ``` Even if `Foo` has a synchronous unwind table, we still need to insert call frame information into `BB3` so that unwinding the call stack from `BB3` or `BB4` works properly.
1 parent 6e98d8b commit e77489d

File tree

6 files changed

+47
-32
lines changed

6 files changed

+47
-32
lines changed

llvm/include/llvm/CodeGen/TargetFrameLowering.h

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020
#include <vector>
2121

2222
namespace llvm {
23-
class BitVector;
24-
class CalleeSavedInfo;
25-
class MachineFunction;
26-
class RegScavenger;
23+
class BitVector;
24+
class CalleeSavedInfo;
25+
class MachineFunction;
26+
class RegScavenger;
2727

2828
namespace TargetStackID {
2929
enum Value {
@@ -45,8 +45,8 @@ enum Value {
4545
class TargetFrameLowering {
4646
public:
4747
enum StackDirection {
48-
StackGrowsUp, // Adding to the stack increases the stack address
49-
StackGrowsDown // Adding to the stack decreases the stack address
48+
StackGrowsUp, // Adding to the stack increases the stack address
49+
StackGrowsDown // Adding to the stack decreases the stack address
5050
};
5151

5252
// Maps a callee saved register to a stack slot with a fixed offset.
@@ -78,6 +78,7 @@ class TargetFrameLowering {
7878
Align TransientStackAlignment;
7979
int LocalAreaOffset;
8080
bool StackRealignable;
81+
8182
public:
8283
TargetFrameLowering(StackDirection D, Align StackAl, int LAO,
8384
Align TransAl = Align(1), bool StackReal = true)
@@ -128,9 +129,7 @@ class TargetFrameLowering {
128129

129130
/// isStackRealignable - This method returns whether the stack can be
130131
/// realigned.
131-
bool isStackRealignable() const {
132-
return StackRealignable;
133-
}
132+
bool isStackRealignable() const { return StackRealignable; }
134133

135134
/// This method returns whether or not it is safe for an object with the
136135
/// given stack id to be bundled into the local area.
@@ -148,8 +147,8 @@ class TargetFrameLowering {
148147
///
149148
/// If this returns true, the frame indexes used by the RegScavenger will be
150149
/// allocated closest to the incoming stack pointer.
151-
virtual bool allocateScavengingFrameIndexesNearIncomingSP(
152-
const MachineFunction &MF) const;
150+
virtual bool
151+
allocateScavengingFrameIndexesNearIncomingSP(const MachineFunction &MF) const;
153152

154153
/// assignCalleeSavedSpillSlots - Allows target to override spill slot
155154
/// assignment logic. If implemented, assignCalleeSavedSpillSlots() should
@@ -190,9 +189,7 @@ class TargetFrameLowering {
190189
/// targetHandlesStackFrameRounding - Returns true if the target is
191190
/// responsible for rounding up the stack frame (probably at emitPrologue
192191
/// time).
193-
virtual bool targetHandlesStackFrameRounding() const {
194-
return false;
195-
}
192+
virtual bool targetHandlesStackFrameRounding() const { return false; }
196193

197194
/// Returns true if the target will correctly handle shrink wrapping.
198195
virtual bool enableShrinkWrapping(const MachineFunction &MF) const {
@@ -229,10 +226,16 @@ class TargetFrameLowering {
229226

230227
/// Returns true if we may need to fix the unwind information for the
231228
/// function.
232-
virtual bool enableCFIFixup(MachineFunction &MF) const;
229+
virtual bool enableCFIFixup(const MachineFunction &MF) const;
230+
231+
/// enableBlockLevelCFIFixup - Returns true if we may need to fix up the
232+
/// function at a basic block level (e.g. for async unwind tables).
233+
virtual bool enableBlockLevelCFIFixup(const MachineFunction &MF) const {
234+
return enableCFIFixup(MF);
235+
};
233236

234237
/// Emit CFI instructions that recreate the state of the unwind information
235-
/// upon fucntion entry.
238+
/// upon function entry.
236239
virtual void resetCFIToInitialState(MachineBasicBlock &MBB) const {}
237240

238241
/// Replace a StackProbe stub (if any) with the actual probe code inline
@@ -352,7 +355,7 @@ class TargetFrameLowering {
352355
/// Returns the callee-saved registers as computed by determineCalleeSaves
353356
/// in the BitVector \p SavedRegs.
354357
virtual void getCalleeSaves(const MachineFunction &MF,
355-
BitVector &SavedRegs) const;
358+
BitVector &SavedRegs) const;
356359

357360
/// This method determines which of the registers reported by
358361
/// TargetRegisterInfo::getCalleeSavedRegs() should actually get saved.
@@ -372,9 +375,9 @@ class TargetFrameLowering {
372375
/// finalized. Once the frame is finalized, MO_FrameIndex operands are
373376
/// replaced with direct constants. This method is optional.
374377
///
375-
virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF,
376-
RegScavenger *RS = nullptr) const {
377-
}
378+
virtual void
379+
processFunctionBeforeFrameFinalized(MachineFunction &MF,
380+
RegScavenger *RS = nullptr) const {}
378381

379382
/// processFunctionBeforeFrameIndicesReplaced - This method is called
380383
/// immediately before MO_FrameIndex operands are eliminated, but after the
@@ -394,14 +397,12 @@ class TargetFrameLowering {
394397
/// implemented if using call frame setup/destroy pseudo instructions.
395398
/// Returns an iterator pointing to the instruction after the replaced one.
396399
virtual MachineBasicBlock::iterator
397-
eliminateCallFramePseudoInstr(MachineFunction &MF,
398-
MachineBasicBlock &MBB,
400+
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
399401
MachineBasicBlock::iterator MI) const {
400402
llvm_unreachable("Call Frame Pseudo Instructions do not exist on this "
401403
"target!");
402404
}
403405

404-
405406
/// Order the symbols in the local stack frame.
406407
/// The list of objects that we want to order is in \p objectsToAllocate as
407408
/// indices into the MachineFrameInfo. The array can be reordered in any way
@@ -410,8 +411,7 @@ class TargetFrameLowering {
410411
/// By default, just maintain the original order.
411412
virtual void
412413
orderFrameObjects(const MachineFunction &MF,
413-
SmallVectorImpl<int> &objectsToAllocate) const {
414-
}
414+
SmallVectorImpl<int> &objectsToAllocate) const {}
415415

416416
/// Check whether or not the given \p MBB can be used as a prologue
417417
/// for the target.
@@ -457,9 +457,7 @@ class TargetFrameLowering {
457457
static bool isSafeForNoCSROpt(const Function &F);
458458

459459
/// Check if the no-CSR optimisation is profitable for the given function.
460-
virtual bool isProfitableForNoCSROpt(const Function &F) const {
461-
return true;
462-
}
460+
virtual bool isProfitableForNoCSROpt(const Function &F) const { return true; }
463461

464462
/// Return initial CFA offset value i.e. the one valid at the beginning of the
465463
/// function (before any stack operations).
@@ -486,6 +484,6 @@ class TargetFrameLowering {
486484
virtual bool hasFPImpl(const MachineFunction &MF) const = 0;
487485
};
488486

489-
} // End llvm namespace
487+
} // namespace llvm
490488

491489
#endif

llvm/lib/CodeGen/CFIFixup.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
#include "llvm/CodeGen/TargetSubtargetInfo.h"
8181
#include "llvm/MC/MCAsmInfo.h"
8282
#include "llvm/MC/MCDwarf.h"
83+
#include "llvm/Support/CodeGen.h"
8384
#include "llvm/Target/TargetMachine.h"
8485

8586
#include <iterator>
@@ -249,6 +250,10 @@ fixupBlock(MachineBasicBlock &CurrBB, const BlockFlagsVector &BlockInfo,
249250
if (!Info.Reachable)
250251
return false;
251252

253+
// If we don't need to fix up CFI at the block level, we only need to fix up the first basic block in the section.
254+
if (!TFL.enableBlockLevelCFIFixup(MF) && !CurrBB.isBeginSection())
255+
return false;
256+
252257
// If the previous block and the current block are in the same section,
253258
// the frame info will propagate from the previous block to the current one.
254259
const BlockFlags &PrevInfo =

llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ bool TargetFrameLowering::enableCalleeSaveSkip(const MachineFunction &MF) const
3535
return false;
3636
}
3737

38-
bool TargetFrameLowering::enableCFIFixup(MachineFunction &MF) const {
38+
bool TargetFrameLowering::enableCFIFixup(const MachineFunction &MF) const {
3939
return MF.needsFrameMoves() &&
4040
!MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
4141
}

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2609,8 +2609,14 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
26092609
}
26102610
}
26112611

2612-
bool AArch64FrameLowering::enableCFIFixup(MachineFunction &MF) const {
2612+
bool AArch64FrameLowering::enableCFIFixup(const MachineFunction &MF) const {
26132613
return TargetFrameLowering::enableCFIFixup(MF) &&
2614+
MF.getInfo<AArch64FunctionInfo>()->needsDwarfUnwindInfo(MF);
2615+
}
2616+
2617+
bool AArch64FrameLowering::enableBlockLevelCFIFixup(
2618+
const MachineFunction &MF) const {
2619+
return enableCFIFixup(MF) &&
26142620
MF.getInfo<AArch64FunctionInfo>()->needsAsyncDwarfUnwindInfo(MF);
26152621
}
26162622

llvm/lib/Target/AArch64/AArch64FrameLowering.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ class AArch64FrameLowering : public TargetFrameLowering {
3636
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
3737
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
3838

39-
bool enableCFIFixup(MachineFunction &MF) const override;
39+
bool enableCFIFixup(const MachineFunction &MF) const override;
40+
41+
bool enableBlockLevelCFIFixup(const MachineFunction &MF) const override;
4042

4143
bool canUseAsPrologue(const MachineBasicBlock &MBB) const override;
4244

llvm/test/CodeGen/AArch64/cfi-fixup-multi-section.mir

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,10 @@ body: |
285285
; CHECK-NEXT: successors: %bb.5(0x80000000)
286286
; CHECK-NEXT: liveins: $w0
287287
; CHECK-NEXT: {{ $}}
288+
; CHECK-NEXT: frame-setup CFI_INSTRUCTION escape 0x16, 0x12, 0x02, 0x82, 0x78
289+
; CHECK-NEXT: frame-setup CFI_INSTRUCTION negate_ra_sign_state
290+
; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 16
291+
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $w30, -16
288292
; CHECK-NEXT: renamable $w0 = nsw SUBWri killed renamable $w0, 1, 0
289293
; CHECK-NEXT: BL @g, csr_aarch64_aapcs_scs, implicit-def dead $lr, implicit $sp, implicit killed $w0, implicit-def $sp, implicit-def $w0
290294
; CHECK-NEXT: renamable $w0 = nsw ADDWri killed renamable $w0, 1, 0

0 commit comments

Comments
 (0)