Skip to content

Commit 4f9d1e7

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 7890919 commit 4f9d1e7

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;
@@ -1216,9 +1217,17 @@ class MachineBasicBlock
12161217
void setNumber(int N) { Number = N; }
12171218

12181219
/// Return the call frame size on entry to this basic block.
1219-
unsigned getCallFrameSize() const { return CallFrameSize; }
1220+
std::optional<unsigned> getCallFrameSize() const { return CallFrameSize; }
1221+
1222+
/// Return the call frame size on entry to this basic block if it is part of a
1223+
/// call sequence and 0 otherwise.
1224+
unsigned getCallFrameSizeOrZero() const { return CallFrameSize.value_or(0); }
1225+
12201226
/// Set the call frame size on entry to this basic block.
1221-
void setCallFrameSize(unsigned N) { CallFrameSize = N; }
1227+
void setCallFrameSize(std::optional<unsigned> N) { CallFrameSize = N; }
1228+
1229+
/// Reset the stored call frame size.
1230+
void clearCallFrameSize() { CallFrameSize.reset(); }
12221231

12231232
/// Return the MCSymbol for this basic block.
12241233
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
@@ -3894,11 +3894,11 @@ void MachineVerifier::verifyStackFrame() {
38943894
BBState.ExitIsSetup = BBState.EntryIsSetup;
38953895
}
38963896

3897-
if ((int)MBB->getCallFrameSize() != -BBState.EntryValue) {
3897+
if ((int)MBB->getCallFrameSizeOrZero() != -BBState.EntryValue) {
38983898
report("Call frame size on entry does not match value computed from "
38993899
"predecessor",
39003900
MBB);
3901-
OS << "Call frame size on entry " << MBB->getCallFrameSize()
3901+
OS << "Call frame size on entry " << MBB->getCallFrameSizeOrZero()
39023902
<< " does not match value computed from predecessor "
39033903
<< -BBState.EntryValue << '\n';
39043904
}

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
@@ -11581,7 +11581,7 @@ ARMTargetLowering::EmitStructByval(MachineInstr &MI,
1158111581
MF->insert(It, exitMBB);
1158211582

1158311583
// Set the call frame size on entry to the new basic blocks.
11584-
unsigned CallFrameSize = TII->getCallFrameSizeAt(MI);
11584+
std::optional<unsigned> CallFrameSize = TII->getCallFrameSizeAt(MI);
1158511585
loopMBB->setCallFrameSize(CallFrameSize);
1158611586
exitMBB->setCallFrameSize(CallFrameSize);
1158711587

@@ -12182,7 +12182,7 @@ ARMTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
1218212182
F->insert(It, sinkMBB);
1218312183

1218412184
// Set the call frame size on entry to the new basic blocks.
12185-
unsigned CallFrameSize = TII->getCallFrameSizeAt(MI);
12185+
std::optional<unsigned> CallFrameSize = TII->getCallFrameSizeAt(MI);
1218612186
copy0MBB->setCallFrameSize(CallFrameSize);
1218712187
sinkMBB->setCallFrameSize(CallFrameSize);
1218812188

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
@@ -13151,7 +13151,7 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
1315113151

1315213152
// Set the call frame size on entry to the new basic blocks.
1315313153
// See https://reviews.llvm.org/D156113.
13154-
unsigned CallFrameSize = TII->getCallFrameSizeAt(MI);
13154+
std::optional<unsigned> CallFrameSize = TII->getCallFrameSizeAt(MI);
1315513155
copy0MBB->setCallFrameSize(CallFrameSize);
1315613156
sinkMBB->setCallFrameSize(CallFrameSize);
1315713157

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

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

1860118601
// Set the call frame size on entry to the new basic blocks.
18602-
unsigned CallFrameSize = TII.getCallFrameSizeAt(*LastSelectPseudo);
18602+
std::optional<unsigned> CallFrameSize =
18603+
TII.getCallFrameSizeAt(*LastSelectPseudo);
1860318604
IfFalseMBB->setCallFrameSize(CallFrameSize);
1860418605
TailMBB->setCallFrameSize(CallFrameSize);
1860518606

llvm/lib/Target/X86/X86ISelLowering.cpp

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

3564935649
// Set the call frame size on entry to the new basic blocks.
35650-
unsigned CallFrameSize = TII->getCallFrameSizeAt(MI);
35650+
std::optional<unsigned> CallFrameSize = TII->getCallFrameSizeAt(MI);
3565135651
FalseMBB->setCallFrameSize(CallFrameSize);
3565235652
SinkMBB->setCallFrameSize(CallFrameSize);
3565335653

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)