Skip to content

Commit 79c40aa

Browse files
committed
[CodeGen] Distinguish zero-sized call frames from no call frame in MachineBB
Call frames can be zero-sized. Distinguishing between instructions in a zero-sized call frame and instructions outside of call frames via the call frame size info stored in the MachineBBs is helpful to avoid nested CALLSEQs (which are illegal and cause machine verifier errors). This patch uses std::optional<unsigned> instead of unsigned to represent call frame sizes. Locations outside of call frames are marked with std::nullopt whereas locations in zero-sized call-frames are represented with a std::optional that contains 0.
1 parent 34b10e1 commit 79c40aa

File tree

14 files changed

+67
-34
lines changed

14 files changed

+67
-34
lines changed

llvm/include/llvm/CodeGen/MachineBasicBlock.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,13 @@ class MachineBasicBlock
146146
int Number;
147147

148148
/// The call frame size on entry to this basic block due to call frame setup
149-
/// instructions in a predecessor. This is usually zero, unless basic blocks
150-
/// are split in the middle of a call sequence.
149+
/// instructions in a predecessor. Usually does not contain a value, unless
150+
/// basic blocks are split in the middle of a call sequence. Zero-sized call
151+
/// frames are possible.
151152
///
152153
/// This information is only maintained until PrologEpilogInserter eliminates
153154
/// call frame pseudos.
154-
unsigned CallFrameSize = 0;
155+
std::optional<unsigned> CallFrameSize;
155156

156157
MachineFunction *xParent;
157158
Instructions Insts;
@@ -1210,9 +1211,17 @@ class MachineBasicBlock
12101211
void setNumber(int N) { Number = N; }
12111212

12121213
/// Return the call frame size on entry to this basic block.
1213-
unsigned getCallFrameSize() const { return CallFrameSize; }
1214+
std::optional<unsigned> getCallFrameSize() const { return CallFrameSize; }
1215+
1216+
/// Return the call frame size on entry to this basic block if it is part of a
1217+
/// call sequence and 0 otherwise.
1218+
unsigned getCallFrameSizeOrZero() const { return CallFrameSize.value_or(0); }
1219+
12141220
/// Set the call frame size on entry to this basic block.
1215-
void setCallFrameSize(unsigned N) { CallFrameSize = N; }
1221+
void setCallFrameSize(std::optional<unsigned> N) { CallFrameSize = N; }
1222+
1223+
/// Reset the stored call frame size.
1224+
void clearCallFrameSize() { CallFrameSize.reset(); }
12161225

12171226
/// Return the MCSymbol for this basic block.
12181227
MCSymbol *getSymbol() const;

llvm/include/llvm/CodeGen/TargetInstrInfo.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2265,8 +2265,9 @@ class TargetInstrInfo : public MCInstrInfo {
22652265
return false;
22662266
}
22672267

2268-
// Get the call frame size just before MI.
2269-
unsigned getCallFrameSizeAt(MachineInstr &MI) const;
2268+
/// Get the call frame size just before MI. Contains no value if MI is not in
2269+
/// a call sequence. Zero-sized call frames are possible.
2270+
std::optional<unsigned> getCallFrameSizeAt(MachineInstr &MI) const;
22702271

22712272
/// Fills in the necessary MachineOperands to refer to a frame index.
22722273
/// The best way to understand this is to print `asm(""::"m"(x));` after

llvm/lib/CodeGen/MIRParser/MIParser.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ class MIParser {
502502
bool parseAddrspace(unsigned &Addrspace);
503503
bool parseSectionID(std::optional<MBBSectionID> &SID);
504504
bool parseBBID(std::optional<UniqueBBID> &BBID);
505-
bool parseCallFrameSize(unsigned &CallFrameSize);
505+
bool parseCallFrameSize(std::optional<unsigned> &CallFrameSize);
506506
bool parseOperandsOffset(MachineOperand &Op);
507507
bool parseIRValue(const Value *&V);
508508
bool parseMemoryOperandFlag(MachineMemOperand::Flags &Flags);
@@ -685,7 +685,7 @@ bool MIParser::parseBBID(std::optional<UniqueBBID> &BBID) {
685685
}
686686

687687
// Parse basic block call frame size.
688-
bool MIParser::parseCallFrameSize(unsigned &CallFrameSize) {
688+
bool MIParser::parseCallFrameSize(std::optional<unsigned> &CallFrameSize) {
689689
assert(Token.is(MIToken::kw_call_frame_size));
690690
lex();
691691
unsigned Value = 0;
@@ -713,7 +713,7 @@ bool MIParser::parseBasicBlockDefinition(
713713
std::optional<MBBSectionID> SectionID;
714714
uint64_t Alignment = 0;
715715
std::optional<UniqueBBID> BBID;
716-
unsigned CallFrameSize = 0;
716+
std::optional<unsigned> CallFrameSize;
717717
BasicBlock *BB = nullptr;
718718
if (consumeIfPresent(MIToken::lparen)) {
719719
do {

llvm/lib/CodeGen/MachineBasicBlock.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -578,9 +578,9 @@ void MachineBasicBlock::printName(raw_ostream &os, unsigned printNameFlags,
578578
os << " " << getBBID()->CloneID;
579579
hasAttributes = true;
580580
}
581-
if (CallFrameSize != 0) {
581+
if (CallFrameSize.has_value()) {
582582
os << (hasAttributes ? ", " : " (");
583-
os << "call-frame-size " << CallFrameSize;
583+
os << "call-frame-size " << CallFrameSize.value();
584584
hasAttributes = true;
585585
}
586586
}

llvm/lib/CodeGen/MachineVerifier.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3837,11 +3837,11 @@ void MachineVerifier::verifyStackFrame() {
38373837
BBState.ExitIsSetup = BBState.EntryIsSetup;
38383838
}
38393839

3840-
if ((int)MBB->getCallFrameSize() != -BBState.EntryValue) {
3840+
if ((int)MBB->getCallFrameSizeOrZero() != -BBState.EntryValue) {
38413841
report("Call frame size on entry does not match value computed from "
38423842
"predecessor",
38433843
MBB);
3844-
errs() << "Call frame size on entry " << MBB->getCallFrameSize()
3844+
errs() << "Call frame size on entry " << MBB->getCallFrameSizeOrZero()
38453845
<< " does not match value computed from predecessor "
38463846
<< -BBState.EntryValue << '\n';
38473847
}

llvm/lib/CodeGen/PrologEpilogInserter.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -392,9 +392,9 @@ void PEI::calculateCallFrameInfo(MachineFunction &MF) {
392392
TFI->eliminateCallFramePseudoInstr(MF, *I->getParent(), I);
393393

394394
// We can't track the call frame size after call frame pseudos have been
395-
// eliminated. Set it to zero everywhere to keep MachineVerifier happy.
395+
// eliminated. Clear it everywhere to keep MachineVerifier happy.
396396
for (MachineBasicBlock &MBB : MF)
397-
MBB.setCallFrameSize(0);
397+
MBB.clearCallFrameSize();
398398
}
399399
}
400400

@@ -1350,20 +1350,20 @@ void PEI::replaceFrameIndicesBackward(MachineFunction &MF) {
13501350
// Get the SP adjustment for the end of MBB from the start of any of its
13511351
// successors. They should all be the same.
13521352
assert(all_of(MBB.successors(), [&MBB](const MachineBasicBlock *Succ) {
1353-
return Succ->getCallFrameSize() ==
1354-
(*MBB.succ_begin())->getCallFrameSize();
1353+
return Succ->getCallFrameSizeOrZero() ==
1354+
(*MBB.succ_begin())->getCallFrameSizeOrZero();
13551355
}));
13561356
const MachineBasicBlock &FirstSucc = **MBB.succ_begin();
1357-
SPAdj = TFI.alignSPAdjust(FirstSucc.getCallFrameSize());
1357+
SPAdj = TFI.alignSPAdjust(FirstSucc.getCallFrameSizeOrZero());
13581358
if (TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsUp)
13591359
SPAdj = -SPAdj;
13601360
}
13611361

13621362
replaceFrameIndicesBackward(&MBB, MF, SPAdj);
13631363

13641364
// We can't track the call frame size after call frame pseudos have been
1365-
// eliminated. Set it to zero everywhere to keep MachineVerifier happy.
1366-
MBB.setCallFrameSize(0);
1365+
// eliminated. Clear it everywhere to keep MachineVerifier happy.
1366+
MBB.clearCallFrameSize();
13671367
}
13681368
}
13691369

@@ -1373,15 +1373,15 @@ void PEI::replaceFrameIndices(MachineFunction &MF) {
13731373
const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering();
13741374

13751375
for (auto &MBB : MF) {
1376-
int SPAdj = TFI.alignSPAdjust(MBB.getCallFrameSize());
1376+
int SPAdj = TFI.alignSPAdjust(MBB.getCallFrameSizeOrZero());
13771377
if (TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsUp)
13781378
SPAdj = -SPAdj;
13791379

13801380
replaceFrameIndices(&MBB, MF, SPAdj);
13811381

13821382
// We can't track the call frame size after call frame pseudos have been
1383-
// eliminated. Set it to zero everywhere to keep MachineVerifier happy.
1384-
MBB.setCallFrameSize(0);
1383+
// eliminated. Clear it everywhere to keep MachineVerifier happy.
1384+
MBB.clearCallFrameSize();
13851385
}
13861386
}
13871387

llvm/lib/CodeGen/TargetInstrInfo.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,15 +1624,15 @@ TargetInstrInfo::describeLoadedValue(const MachineInstr &MI,
16241624
return std::nullopt;
16251625
}
16261626

1627-
// Get the call frame size just before MI.
1628-
unsigned TargetInstrInfo::getCallFrameSizeAt(MachineInstr &MI) const {
1627+
std::optional<unsigned>
1628+
TargetInstrInfo::getCallFrameSizeAt(MachineInstr &MI) const {
16291629
// Search backwards from MI for the most recent call frame instruction.
16301630
MachineBasicBlock *MBB = MI.getParent();
16311631
for (auto &AdjI : reverse(make_range(MBB->instr_begin(), MI.getIterator()))) {
16321632
if (AdjI.getOpcode() == getCallFrameSetupOpcode())
16331633
return getFrameTotalSize(AdjI);
16341634
if (AdjI.getOpcode() == getCallFrameDestroyOpcode())
1635-
return 0;
1635+
return std::nullopt;
16361636
}
16371637

16381638
// If none was found, use the call frame size from the start of the basic

llvm/lib/Target/ARM/ARMISelLowering.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11594,7 +11594,7 @@ ARMTargetLowering::EmitStructByval(MachineInstr &MI,
1159411594
MF->insert(It, exitMBB);
1159511595

1159611596
// Set the call frame size on entry to the new basic blocks.
11597-
unsigned CallFrameSize = TII->getCallFrameSizeAt(MI);
11597+
std::optional<unsigned> CallFrameSize = TII->getCallFrameSizeAt(MI);
1159811598
loopMBB->setCallFrameSize(CallFrameSize);
1159911599
exitMBB->setCallFrameSize(CallFrameSize);
1160011600

@@ -12195,7 +12195,7 @@ ARMTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
1219512195
F->insert(It, sinkMBB);
1219612196

1219712197
// Set the call frame size on entry to the new basic blocks.
12198-
unsigned CallFrameSize = TII->getCallFrameSizeAt(MI);
12198+
std::optional<unsigned> CallFrameSize = TII->getCallFrameSizeAt(MI);
1219912199
copy0MBB->setCallFrameSize(CallFrameSize);
1220012200
sinkMBB->setCallFrameSize(CallFrameSize);
1220112201

llvm/lib/Target/AVR/AVRISelLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2424,7 +2424,7 @@ AVRTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
24242424
MF->insert(I, falseMBB);
24252425

24262426
// Set the call frame size on entry to the new basic blocks.
2427-
unsigned CallFrameSize = TII.getCallFrameSizeAt(MI);
2427+
std::optional<unsigned> CallFrameSize = TII.getCallFrameSizeAt(MI);
24282428
trueMBB->setCallFrameSize(CallFrameSize);
24292429
falseMBB->setCallFrameSize(CallFrameSize);
24302430

llvm/lib/Target/M68k/M68kISelLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3199,7 +3199,7 @@ M68kTargetLowering::EmitLoweredSelect(MachineInstr &MI,
31993199
F->insert(It, SinkMBB);
32003200

32013201
// Set the call frame size on entry to the new basic blocks.
3202-
unsigned CallFrameSize = TII->getCallFrameSizeAt(MI);
3202+
std::optional<unsigned> CallFrameSize = TII->getCallFrameSizeAt(MI);
32033203
Copy0MBB->setCallFrameSize(CallFrameSize);
32043204
SinkMBB->setCallFrameSize(CallFrameSize);
32053205

llvm/lib/Target/PowerPC/PPCISelLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13031,7 +13031,7 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
1303113031

1303213032
// Set the call frame size on entry to the new basic blocks.
1303313033
// See https://reviews.llvm.org/D156113.
13034-
unsigned CallFrameSize = TII->getCallFrameSizeAt(MI);
13034+
std::optional<unsigned> CallFrameSize = TII->getCallFrameSizeAt(MI);
1303513035
copy0MBB->setCallFrameSize(CallFrameSize);
1303613036
sinkMBB->setCallFrameSize(CallFrameSize);
1303713037

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18444,7 +18444,8 @@ static MachineBasicBlock *emitSelectPseudo(MachineInstr &MI,
1844418444
F->insert(I, TailMBB);
1844518445

1844618446
// Set the call frame size on entry to the new basic blocks.
18447-
unsigned CallFrameSize = TII.getCallFrameSizeAt(*LastSelectPseudo);
18447+
std::optional<unsigned> CallFrameSize =
18448+
TII.getCallFrameSizeAt(*LastSelectPseudo);
1844818449
IfFalseMBB->setCallFrameSize(CallFrameSize);
1844918450
TailMBB->setCallFrameSize(CallFrameSize);
1845018451

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35264,7 +35264,7 @@ X86TargetLowering::EmitLoweredSelect(MachineInstr &MI,
3526435264
F->insert(It, SinkMBB);
3526535265

3526635266
// Set the call frame size on entry to the new basic blocks.
35267-
unsigned CallFrameSize = TII->getCallFrameSizeAt(MI);
35267+
std::optional<unsigned> CallFrameSize = TII->getCallFrameSizeAt(MI);
3526835268
FalseMBB->setCallFrameSize(CallFrameSize);
3526935269
SinkMBB->setCallFrameSize(CallFrameSize);
3527035270

llvm/test/CodeGen/MIR/ARM/call-frame-size.mir

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,25 @@ body: |
2323
ADJCALLSTACKUP 100, 0, 14, $noreg, implicit-def $sp, implicit $sp
2424
bb.2:
2525
...
26+
27+
---
28+
name: callframesizezero
29+
body: |
30+
; CHECK-LABEL: name: callframesizezero
31+
; CHECK: bb.0:
32+
; CHECK-NEXT: successors: %bb.1(0x80000000)
33+
; CHECK-NEXT: {{ $}}
34+
; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp
35+
; CHECK-NEXT: {{ $}}
36+
; CHECK-NEXT: bb.1 (call-frame-size 0):
37+
; CHECK-NEXT: successors: %bb.2(0x80000000)
38+
; CHECK-NEXT: {{ $}}
39+
; CHECK-NEXT: ADJCALLSTACKUP 0, 0, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp
40+
; CHECK-NEXT: {{ $}}
41+
; CHECK-NEXT: bb.2:
42+
bb.0:
43+
ADJCALLSTACKDOWN 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
44+
bb.1 (call-frame-size 0):
45+
ADJCALLSTACKUP 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
46+
bb.2:
47+
...

0 commit comments

Comments
 (0)