-
Notifications
You must be signed in to change notification settings - Fork 14.6k
[llvm] Support multiple save/restore points in mir #119357
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 2 commits
baaea8d
bd3c367
fb9d9c3
7409014
a1ce745
dbd5890
85c1c07
1703639
447f5f1
9000dec
ee753d6
98fc28e
2d4c879
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -631,6 +631,55 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::CalledGlobal) | |
namespace llvm { | ||
namespace yaml { | ||
|
||
// Struct representing one save/restore point in the 'savePoint'/'restorePoint' | ||
// list | ||
struct SaveRestorePointEntry { | ||
StringValue Point; | ||
|
||
bool operator==(const SaveRestorePointEntry &Other) const { | ||
return Point == Other.Point; | ||
} | ||
}; | ||
|
||
using SaveRestorePoints = | ||
std::variant<std::vector<SaveRestorePointEntry>, StringValue>; | ||
|
||
template <> struct PolymorphicTraits<SaveRestorePoints> { | ||
|
||
static NodeKind getKind(const SaveRestorePoints &SRPoints) { | ||
if (std::holds_alternative<std::vector<SaveRestorePointEntry>>(SRPoints)) | ||
return NodeKind::Sequence; | ||
if (std::holds_alternative<StringValue>(SRPoints)) | ||
return NodeKind::Scalar; | ||
llvm_unreachable("Unsupported NodeKind of SaveRestorePoints"); | ||
} | ||
|
||
static SaveRestorePointEntry &getAsMap(SaveRestorePoints &SRPoints) { | ||
llvm_unreachable("SaveRestorePoints can't be represented as Map"); | ||
} | ||
|
||
static std::vector<SaveRestorePointEntry> & | ||
getAsSequence(SaveRestorePoints &SRPoints) { | ||
if (!std::holds_alternative<std::vector<SaveRestorePointEntry>>(SRPoints)) | ||
SRPoints = std::vector<SaveRestorePointEntry>(); | ||
|
||
return std::get<std::vector<SaveRestorePointEntry>>(SRPoints); | ||
} | ||
|
||
static StringValue &getAsScalar(SaveRestorePoints &SRPoints) { | ||
if (!std::holds_alternative<StringValue>(SRPoints)) | ||
SRPoints = StringValue(); | ||
|
||
return std::get<StringValue>(SRPoints); | ||
} | ||
}; | ||
|
||
template <> struct MappingTraits<SaveRestorePointEntry> { | ||
static void mapping(IO &YamlIO, SaveRestorePointEntry &Entry) { | ||
YamlIO.mapRequired("point", Entry.Point); | ||
} | ||
}; | ||
|
||
template <> struct MappingTraits<MachineJumpTable> { | ||
static void mapping(IO &YamlIO, MachineJumpTable &JT) { | ||
YamlIO.mapRequired("kind", JT.Kind); | ||
|
@@ -639,6 +688,14 @@ template <> struct MappingTraits<MachineJumpTable> { | |
} | ||
}; | ||
|
||
} // namespace yaml | ||
} // namespace llvm | ||
|
||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::SaveRestorePointEntry) | ||
|
||
namespace llvm { | ||
namespace yaml { | ||
|
||
/// Serializable representation of MachineFrameInfo. | ||
/// | ||
/// Doesn't serialize attributes like 'StackAlignment', 'IsStackRealignable' and | ||
|
@@ -666,8 +723,8 @@ struct MachineFrameInfo { | |
bool HasTailCall = false; | ||
bool IsCalleeSavedInfoValid = false; | ||
unsigned LocalFrameSize = 0; | ||
StringValue SavePoint; | ||
StringValue RestorePoint; | ||
SaveRestorePoints SavePoints; | ||
SaveRestorePoints RestorePoints; | ||
|
||
bool operator==(const MachineFrameInfo &Other) const { | ||
return IsFrameAddressTaken == Other.IsFrameAddressTaken && | ||
|
@@ -688,7 +745,8 @@ struct MachineFrameInfo { | |
HasMustTailInVarArgFunc == Other.HasMustTailInVarArgFunc && | ||
HasTailCall == Other.HasTailCall && | ||
LocalFrameSize == Other.LocalFrameSize && | ||
SavePoint == Other.SavePoint && RestorePoint == Other.RestorePoint && | ||
SavePoints == Other.SavePoints && | ||
RestorePoints == Other.RestorePoints && | ||
IsCalleeSavedInfoValid == Other.IsCalleeSavedInfoValid; | ||
} | ||
}; | ||
|
@@ -720,10 +778,14 @@ template <> struct MappingTraits<MachineFrameInfo> { | |
YamlIO.mapOptional("isCalleeSavedInfoValid", MFI.IsCalleeSavedInfoValid, | ||
false); | ||
YamlIO.mapOptional("localFrameSize", MFI.LocalFrameSize, (unsigned)0); | ||
YamlIO.mapOptional("savePoint", MFI.SavePoint, | ||
StringValue()); // Don't print it out when it's empty. | ||
YamlIO.mapOptional("restorePoint", MFI.RestorePoint, | ||
StringValue()); // Don't print it out when it's empty. | ||
YamlIO.mapOptional( | ||
"savePoint", MFI.SavePoints, | ||
SaveRestorePoints( | ||
StringValue())); // Don't print it out when it's empty. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Empty list? |
||
YamlIO.mapOptional( | ||
"restorePoint", MFI.RestorePoints, | ||
SaveRestorePoints( | ||
StringValue())); // Don't print it out when it's empty. | ||
} | ||
}; | ||
|
||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -124,6 +124,10 @@ class MIRParserImpl { | |||||
bool initializeFrameInfo(PerFunctionMIParsingState &PFS, | ||||||
const yaml::MachineFunction &YamlMF); | ||||||
|
||||||
bool initializeSaveRestorePoints(PerFunctionMIParsingState &PFS, | ||||||
const yaml::SaveRestorePoints &YamlSRPoints, | ||||||
bool IsSavePoints); | ||||||
|
||||||
bool initializeCallSiteInfo(PerFunctionMIParsingState &PFS, | ||||||
const yaml::MachineFunction &YamlMF); | ||||||
|
||||||
|
@@ -851,18 +855,12 @@ bool MIRParserImpl::initializeFrameInfo(PerFunctionMIParsingState &PFS, | |||||
MFI.setHasTailCall(YamlMFI.HasTailCall); | ||||||
MFI.setCalleeSavedInfoValid(YamlMFI.IsCalleeSavedInfoValid); | ||||||
MFI.setLocalFrameSize(YamlMFI.LocalFrameSize); | ||||||
if (!YamlMFI.SavePoint.Value.empty()) { | ||||||
MachineBasicBlock *MBB = nullptr; | ||||||
if (parseMBBReference(PFS, MBB, YamlMFI.SavePoint)) | ||||||
return true; | ||||||
MFI.setSavePoint(MBB); | ||||||
} | ||||||
if (!YamlMFI.RestorePoint.Value.empty()) { | ||||||
MachineBasicBlock *MBB = nullptr; | ||||||
if (parseMBBReference(PFS, MBB, YamlMFI.RestorePoint)) | ||||||
return true; | ||||||
MFI.setRestorePoint(MBB); | ||||||
} | ||||||
if (initializeSaveRestorePoints(PFS, YamlMFI.SavePoints, | ||||||
true /*IsSavePoints*/)) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. addressed |
||||||
return true; | ||||||
if (initializeSaveRestorePoints(PFS, YamlMFI.RestorePoints, | ||||||
false /*IsSavePoints*/)) | ||||||
return true; | ||||||
|
||||||
std::vector<CalleeSavedInfo> CSIInfo; | ||||||
// Initialize the fixed frame objects. | ||||||
|
@@ -1077,6 +1075,41 @@ bool MIRParserImpl::initializeConstantPool(PerFunctionMIParsingState &PFS, | |||||
return false; | ||||||
} | ||||||
|
||||||
// Return true if basic block was incorrectly specified in MIR | ||||||
bool MIRParserImpl::initializeSaveRestorePoints( | ||||||
michaelmaitland marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
PerFunctionMIParsingState &PFS, const yaml::SaveRestorePoints &YamlSRPoints, | ||||||
bool IsSavePoints) { | ||||||
MachineBasicBlock *MBB = nullptr; | ||||||
if (std::holds_alternative<std::vector<yaml::SaveRestorePointEntry>>( | ||||||
YamlSRPoints)) { | ||||||
const auto &VectorRepr = | ||||||
std::get<std::vector<yaml::SaveRestorePointEntry>>(YamlSRPoints); | ||||||
if (VectorRepr.empty()) | ||||||
return false; | ||||||
|
||||||
const auto &Entry = VectorRepr.front(); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unless I'm missing something from the code structure, you're only parsing the first bb reference here. Also, you don't seem to have any tests for round tripping MIR with multiple save restore points. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Test was added, code fixed |
||||||
const auto &MBBSource = Entry.Point; | ||||||
if (parseMBBReference(PFS, MBB, MBBSource.Value)) | ||||||
return true; | ||||||
} else { | ||||||
yaml::StringValue StringRepr = std::get<yaml::StringValue>(YamlSRPoints); | ||||||
if (StringRepr.Value.empty()) | ||||||
return false; | ||||||
if (parseMBBReference(PFS, MBB, StringRepr)) | ||||||
return true; | ||||||
} | ||||||
|
||||||
MachineFunction &MF = PFS.MF; | ||||||
MachineFrameInfo &MFI = MF.getFrameInfo(); | ||||||
|
||||||
if (IsSavePoints) | ||||||
MFI.setSavePoint(MBB); | ||||||
else | ||||||
MFI.setRestorePoint(MBB); | ||||||
|
||||||
return false; | ||||||
} | ||||||
|
||||||
bool MIRParserImpl::initializeJumpTableInfo(PerFunctionMIParsingState &PFS, | ||||||
const yaml::MachineJumpTable &YamlJTI) { | ||||||
MachineJumpTableInfo *JTI = PFS.MF.getOrCreateJumpTableInfo(YamlJTI.Kind); | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -118,6 +118,8 @@ class MIRPrinter { | |
const TargetRegisterInfo *TRI); | ||
void convert(ModuleSlotTracker &MST, yaml::MachineFrameInfo &YamlMFI, | ||
const MachineFrameInfo &MFI); | ||
void convert(ModuleSlotTracker &MST, yaml::SaveRestorePoints &YamlSRPoints, | ||
MachineBasicBlock *SaveRestorePoint); | ||
void convert(yaml::MachineFunction &MF, | ||
const MachineConstantPool &ConstantPool); | ||
void convert(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI, | ||
|
@@ -397,14 +399,10 @@ void MIRPrinter::convert(ModuleSlotTracker &MST, | |
YamlMFI.HasTailCall = MFI.hasTailCall(); | ||
YamlMFI.IsCalleeSavedInfoValid = MFI.isCalleeSavedInfoValid(); | ||
YamlMFI.LocalFrameSize = MFI.getLocalFrameSize(); | ||
if (MFI.getSavePoint()) { | ||
raw_string_ostream StrOS(YamlMFI.SavePoint.Value); | ||
StrOS << printMBBReference(*MFI.getSavePoint()); | ||
} | ||
if (MFI.getRestorePoint()) { | ||
raw_string_ostream StrOS(YamlMFI.RestorePoint.Value); | ||
StrOS << printMBBReference(*MFI.getRestorePoint()); | ||
} | ||
if (MFI.getSavePoint()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here we have singular getSavePoint, plural YamlMFI.SavePoints, and singular getSavePoint again. It is a little weird that we're mixing singular and plural. This makes me think that we should get rid of SavePoint and RestorePoint and replace it entirely with the plural SavePoints and RestorePoints. By this I mean This could be done in a follow up patch if others agree this would be a good direction to move in. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can do it it the follow up patch. |
||
convert(MST, YamlMFI.SavePoints, MFI.getSavePoint()); | ||
if (MFI.getRestorePoint()) | ||
convert(MST, YamlMFI.RestorePoints, MFI.getRestorePoint()); | ||
} | ||
|
||
void MIRPrinter::convertEntryValueObjects(yaml::MachineFunction &YMF, | ||
|
@@ -646,6 +644,19 @@ void MIRPrinter::convert(yaml::MachineFunction &MF, | |
} | ||
} | ||
|
||
void MIRPrinter::convert(ModuleSlotTracker &MST, | ||
yaml::SaveRestorePoints &YamlSRPoints, | ||
MachineBasicBlock *SRPoint) { | ||
SmallString<16> Str; | ||
yaml::SaveRestorePointEntry Entry; | ||
raw_svector_ostream StrOS(Str); | ||
StrOS << printMBBReference(*SRPoint); | ||
Entry.Point = StrOS.str().str(); | ||
auto &Points = | ||
std::get<std::vector<yaml::SaveRestorePointEntry>>(YamlSRPoints); | ||
Points.push_back(Entry); | ||
} | ||
|
||
void MIRPrinter::convert(ModuleSlotTracker &MST, | ||
yaml::MachineJumpTable &YamlJTI, | ||
const MachineJumpTableInfo &JTI) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand why this is a variant, and not just the vector of points
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Several comments above (#119357 (comment)) @preames suggested to make support for multiple save/restore points backward compatible with single save/restore point approach.
It helped to "cut out a huge amount of spurious diff". So, StringValue in this variant needed for backward compatibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should make no effort to maintain MIR backwards compatibility. As a diff reduction strategy, this can be part 1. But we should absolutely rip out the old form