Skip to content

Commit 00cf017

Browse files
committed
[CodeGen] Compute call frame sizes instead of storing them in MachineBBs
Previously, we would need to update stored call frame sizes whenever a MachineBB with a call sequence is split or call frame instructions are moved. By recomputing them instead, this change avoids the need for keeping track of the call frame sizes throughout transformations. It also fixes several cases where updates of call frame sizes were missing. The overhead according to the compile time tracker is < +0.03% executed instructions on all CT benchmarks. This also allows distinguishing a zero-sized call frame from no open call frame, which is helpful to avoid nested CALLSEQs (which are illegal and cause machine verifier errors).
1 parent 6019707 commit 00cf017

23 files changed

+243
-207
lines changed

llvm/include/llvm/CodeGen/MachineBasicBlock.h

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -145,15 +145,6 @@ class MachineBasicBlock
145145
const BasicBlock *BB;
146146
int Number;
147147

148-
/// The call frame size on entry to this basic block due to call frame setup
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.
152-
///
153-
/// This information is only maintained until PrologEpilogInserter eliminates
154-
/// call frame pseudos.
155-
std::optional<unsigned> CallFrameSize;
156-
157148
MachineFunction *xParent;
158149
Instructions Insts;
159150

@@ -1216,19 +1207,6 @@ class MachineBasicBlock
12161207
int getNumber() const { return Number; }
12171208
void setNumber(int N) { Number = N; }
12181209

1219-
/// Return the call frame size on entry to this basic block.
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-
1226-
/// Set the call frame size on entry to this basic block.
1227-
void setCallFrameSize(std::optional<unsigned> N) { CallFrameSize = N; }
1228-
1229-
/// Reset the stored call frame size.
1230-
void clearCallFrameSize() { CallFrameSize.reset(); }
1231-
12321210
/// Return the MCSymbol for this basic block.
12331211
MCSymbol *getSymbol() const;
12341212

llvm/include/llvm/CodeGen/MachineFrameInfo.h

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ class MachineFunction;
2626
class MachineBasicBlock;
2727
class BitVector;
2828
class AllocaInst;
29+
class MachineFrameSizeInfo;
30+
class TargetInstrInfo;
2931

3032
/// The CalleeSavedInfo class tracks the information need to locate where a
3133
/// callee saved register is in the current frame.
@@ -282,6 +284,10 @@ class MachineFrameInfo {
282284
/// It is only valid during and after prolog/epilog code insertion.
283285
uint64_t MaxCallFrameSize = ~UINT64_C(0);
284286

287+
/// Call frame sizes for the MachineFunction's MachineBasicBlocks. This is set
288+
/// by the MachineFrameSizeInfo constructor and cleared by its destructor.
289+
MachineFrameSizeInfo *SizeInfo = nullptr;
290+
285291
/// The number of bytes of callee saved registers that the target wants to
286292
/// report for the current function in the CodeView S_FRAMEPROC record.
287293
unsigned CVBytesOfCalleeSavedRegisters = 0;
@@ -675,6 +681,13 @@ class MachineFrameInfo {
675681
}
676682
void setMaxCallFrameSize(uint64_t S) { MaxCallFrameSize = S; }
677683

684+
/// Return an object that can be queried for call frame sizes at specific
685+
/// locations in the MachineFunction. Constructing a MachineFrameSizeInfo
686+
/// object for the MachineFunction automatically makes it available via this
687+
/// field during the object's lifetime.
688+
MachineFrameSizeInfo *getSizeInfo() const { return SizeInfo; }
689+
void setSizeInfo(MachineFrameSizeInfo *SI) { SizeInfo = SI; }
690+
678691
/// Returns how many bytes of callee-saved registers the target pushed in the
679692
/// prologue. Only used for debug info.
680693
unsigned getCVBytesOfCalleeSavedRegisters() const {
@@ -846,6 +859,73 @@ class MachineFrameInfo {
846859
void dump(const MachineFunction &MF) const;
847860
};
848861

862+
/// Computes and stores the call frame sizes at the entries and exits of
863+
/// MachineBasicBlocks of a MachineFunction based on call frame setup and
864+
/// destroy pseudo instructions. Usually, no call frame is open at block
865+
/// boundaries, except if a call sequence has been split into multiple blocks.
866+
///
867+
/// Computing this information is deferred until it is queried. Upon
868+
/// construction, a MachineFrameSizeInfo object registers itself in the
869+
/// MachineFunction's MachineFrameInfo (and it unregisters when destructed).
870+
/// While registered, it can be retrieved via MachineFrameInfo::getSizeInfo().
871+
///
872+
/// This class assumes that call frame instructions are placed properly, i.e.,
873+
/// every program path hits a frame destroy of equal size after hitting a frame
874+
/// setup, and a frame setup of equal size before a frame destroy. Nested call
875+
/// frame sequences are not allowed.
876+
class MachineFrameSizeInfo {
877+
public:
878+
MachineFrameSizeInfo(MachineFunction &MF) : MF(MF) {
879+
assert(MF.getFrameInfo().getSizeInfo() == nullptr);
880+
MF.getFrameInfo().setSizeInfo(this);
881+
}
882+
883+
~MachineFrameSizeInfo() { MF.getFrameInfo().setSizeInfo(nullptr); }
884+
885+
/// Get the call frame size just before MI. Contains no value if MI is not in
886+
/// a call sequence. Zero-sized call frames are possible.
887+
std::optional<unsigned> getCallFrameSizeAt(MachineInstr &MI);
888+
889+
/// Get the call frame size just before MII. Contains no value if MII is not
890+
/// in a call sequence. Zero-sized call frames are possible.
891+
std::optional<unsigned> getCallFrameSizeAt(MachineBasicBlock &MBB,
892+
MachineBasicBlock::iterator MII);
893+
894+
/// Get the call frame size at the entry of MBB. Contains no value if the
895+
/// entry of MBB is not in a call sequence. Zero-sized call frames are
896+
/// possible. Prefer this over getCallFrameSizeAt(MBB, MBB.begin()).
897+
std::optional<unsigned> getCallFrameSizeAtBegin(MachineBasicBlock &MBB);
898+
899+
/// Get the call frame size at the exit of MBB. Contains no value if the exit
900+
/// of MBB is not in a call sequence. Zero-sized call frames are possible.
901+
/// Prefer this over getCallFrameSizeAt(MBB, MBB.end()).
902+
std::optional<unsigned> getCallFrameSizeAtEnd(MachineBasicBlock &MBB);
903+
904+
private:
905+
/// Stores the call frame sizes at the boundaries of a MachineBasicBlock.
906+
struct MachineFrameSizeInfoForBB {
907+
MachineFrameSizeInfoForBB() = default;
908+
MachineFrameSizeInfoForBB(std::optional<unsigned> EntryVal,
909+
std::optional<unsigned> ExitVal)
910+
: Entry(EntryVal), Exit(ExitVal) {}
911+
912+
std::optional<unsigned> Entry;
913+
std::optional<unsigned> Exit;
914+
};
915+
916+
/// Compute call frame sizes at the boundaries of each MachineBasicBlock.
917+
void computeSizes();
918+
919+
MachineFunction &MF;
920+
const TargetInstrInfo *TII;
921+
unsigned FrameSetupOpcode = ~0u;
922+
unsigned FrameDestroyOpcode = ~0u;
923+
bool HasFrameOpcodes = false;
924+
bool HasNoBrokenUpCallSeqs = false;
925+
SmallVector<MachineFrameSizeInfoForBB, 8> State;
926+
bool IsComputed = false;
927+
};
928+
849929
} // End llvm namespace
850930

851931
#endif

llvm/include/llvm/CodeGen/TargetInstrInfo.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2265,16 +2265,6 @@ class TargetInstrInfo : public MCInstrInfo {
22652265
return false;
22662266
}
22672267

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;
2271-
2272-
/// Get the call frame size just before MII. Contains no value if MII is not
2273-
/// in a call sequence. Zero-sized call frames are possible.
2274-
std::optional<unsigned>
2275-
getCallFrameSizeAt(MachineBasicBlock &MBB,
2276-
MachineBasicBlock::iterator MII) const;
2277-
22782268
/// Fills in the necessary MachineOperands to refer to a frame index.
22792269
/// The best way to understand this is to print `asm(""::"m"(x));` after
22802270
/// finalize-isel. Example:

llvm/lib/CodeGen/MIRParser/MILexer.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,6 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
285285
.Case("ir-block-address-taken", MIToken::kw_ir_block_address_taken)
286286
.Case("machine-block-address-taken",
287287
MIToken::kw_machine_block_address_taken)
288-
.Case("call-frame-size", MIToken::kw_call_frame_size)
289288
.Case("noconvergent", MIToken::kw_noconvergent)
290289
.Default(MIToken::Identifier);
291290
}

llvm/lib/CodeGen/MIRParser/MILexer.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@ struct MIToken {
139139
kw_unknown_address,
140140
kw_ir_block_address_taken,
141141
kw_machine_block_address_taken,
142-
kw_call_frame_size,
143142
kw_noconvergent,
144143

145144
// Metadata types.

llvm/lib/CodeGen/MIRParser/MIParser.cpp

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,6 @@ class MIParser {
502502
bool parseAddrspace(unsigned &Addrspace);
503503
bool parseSectionID(std::optional<MBBSectionID> &SID);
504504
bool parseBBID(std::optional<UniqueBBID> &BBID);
505-
bool parseCallFrameSize(std::optional<unsigned> &CallFrameSize);
506505
bool parseOperandsOffset(MachineOperand &Op);
507506
bool parseIRValue(const Value *&V);
508507
bool parseMemoryOperandFlag(MachineMemOperand::Flags &Flags);
@@ -684,18 +683,6 @@ bool MIParser::parseBBID(std::optional<UniqueBBID> &BBID) {
684683
return false;
685684
}
686685

687-
// Parse basic block call frame size.
688-
bool MIParser::parseCallFrameSize(std::optional<unsigned> &CallFrameSize) {
689-
assert(Token.is(MIToken::kw_call_frame_size));
690-
lex();
691-
unsigned Value = 0;
692-
if (getUnsigned(Value))
693-
return error("Unknown call frame size");
694-
CallFrameSize = Value;
695-
lex();
696-
return false;
697-
}
698-
699686
bool MIParser::parseBasicBlockDefinition(
700687
DenseMap<unsigned, MachineBasicBlock *> &MBBSlots) {
701688
assert(Token.is(MIToken::MachineBasicBlockLabel));
@@ -713,7 +700,6 @@ bool MIParser::parseBasicBlockDefinition(
713700
std::optional<MBBSectionID> SectionID;
714701
uint64_t Alignment = 0;
715702
std::optional<UniqueBBID> BBID;
716-
std::optional<unsigned> CallFrameSize;
717703
BasicBlock *BB = nullptr;
718704
if (consumeIfPresent(MIToken::lparen)) {
719705
do {
@@ -758,10 +744,6 @@ bool MIParser::parseBasicBlockDefinition(
758744
if (parseBBID(BBID))
759745
return true;
760746
break;
761-
case MIToken::kw_call_frame_size:
762-
if (parseCallFrameSize(CallFrameSize))
763-
return true;
764-
break;
765747
default:
766748
break;
767749
}
@@ -799,7 +781,6 @@ bool MIParser::parseBasicBlockDefinition(
799781
MBB->setSectionID(*SectionID);
800782
MF.setBBSectionsType(BasicBlockSection::List);
801783
}
802-
MBB->setCallFrameSize(CallFrameSize);
803784
return false;
804785
}
805786

llvm/lib/CodeGen/MachineBasicBlock.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -578,11 +578,6 @@ void MachineBasicBlock::printName(raw_ostream &os, unsigned printNameFlags,
578578
os << " " << getBBID()->CloneID;
579579
hasAttributes = true;
580580
}
581-
if (CallFrameSize.has_value()) {
582-
os << (hasAttributes ? ", " : " (");
583-
os << "call-frame-size " << CallFrameSize.value();
584-
hasAttributes = true;
585-
}
586581
}
587582

588583
if (hasAttributes)
@@ -1155,7 +1150,6 @@ MachineBasicBlock *MachineBasicBlock::SplitCriticalEdge(
11551150
MachineBasicBlock *PrevFallthrough = getNextNode();
11561151

11571152
MachineBasicBlock *NMBB = MF->CreateMachineBasicBlock();
1158-
NMBB->setCallFrameSize(Succ->getCallFrameSize());
11591153

11601154
// Is there an indirect jump with jump table?
11611155
bool ChangedIndirectJump = false;

0 commit comments

Comments
 (0)