-
Notifications
You must be signed in to change notification settings - Fork 15.5k
[BOLT][AArch64] Add isPush & isPop #120713
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
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Member
|
@llvm/pr-subscribers-bolt Author: Alexey Moksyakov (yavtuk) ChangesThis functionality is needed for inliner pass and also for correct dyno stats. Needed for PR 1 Files Affected:
diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
index 7e08e5c81d26ff..610309602771c0 100644
--- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
+++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
@@ -133,6 +133,14 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
public:
using MCPlusBuilder::MCPlusBuilder;
+ bool isPush(const MCInst &Inst) const override {
+ return isStoreToStack(Inst);
+ };
+
+ bool isPop(const MCInst &Inst) const override {
+ return isLoadFromStack(Inst);
+ };
+
bool equals(const MCTargetExpr &A, const MCTargetExpr &B,
CompFuncTy Comp) const override {
const auto &AArch64ExprA = cast<AArch64MCExpr>(A);
@@ -214,11 +222,16 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
}
bool isLDRB(const MCInst &Inst) const {
- return (Inst.getOpcode() == AArch64::LDRBBpost ||
+ return (Inst.getOpcode() == AArch64::LDRBpost ||
+ Inst.getOpcode() == AArch64::LDRBBpost ||
Inst.getOpcode() == AArch64::LDRBBpre ||
Inst.getOpcode() == AArch64::LDRBBroW ||
+ Inst.getOpcode() == AArch64::LDRBroW ||
+ Inst.getOpcode() == AArch64::LDRBroX ||
Inst.getOpcode() == AArch64::LDRBBroX ||
Inst.getOpcode() == AArch64::LDRBBui ||
+ Inst.getOpcode() == AArch64::LDRBui ||
+ Inst.getOpcode() == AArch64::LDRBpre ||
Inst.getOpcode() == AArch64::LDRSBWpost ||
Inst.getOpcode() == AArch64::LDRSBWpre ||
Inst.getOpcode() == AArch64::LDRSBWroW ||
@@ -232,11 +245,16 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
}
bool isLDRH(const MCInst &Inst) const {
- return (Inst.getOpcode() == AArch64::LDRHHpost ||
+ return (Inst.getOpcode() == AArch64::LDRHpost ||
+ Inst.getOpcode() == AArch64::LDRHHpost ||
Inst.getOpcode() == AArch64::LDRHHpre ||
+ Inst.getOpcode() == AArch64::LDRHroW ||
Inst.getOpcode() == AArch64::LDRHHroW ||
+ Inst.getOpcode() == AArch64::LDRHroX ||
Inst.getOpcode() == AArch64::LDRHHroX ||
Inst.getOpcode() == AArch64::LDRHHui ||
+ Inst.getOpcode() == AArch64::LDRHui ||
+ Inst.getOpcode() == AArch64::LDRHpre ||
Inst.getOpcode() == AArch64::LDRSHWpost ||
Inst.getOpcode() == AArch64::LDRSHWpre ||
Inst.getOpcode() == AArch64::LDRSHWroW ||
@@ -265,8 +283,150 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
Inst.getOpcode() == AArch64::LDRXui);
}
+ bool isLDRS(const MCInst &Inst) const {
+ return (Inst.getOpcode() == AArch64::LDRSui ||
+ Inst.getOpcode() == AArch64::LDRSWui ||
+ Inst.getOpcode() == AArch64::LDRSWpre ||
+ Inst.getOpcode() == AArch64::LDRSpre ||
+ Inst.getOpcode() == AArch64::LDRSpost ||
+ Inst.getOpcode() == AArch64::LDRSWpost ||
+ Inst.getOpcode() == AArch64::LDRSWroW ||
+ Inst.getOpcode() == AArch64::LDRSWroX ||
+ Inst.getOpcode() == AArch64::LDRSroW ||
+ Inst.getOpcode() == AArch64::LDRSroX);
+ }
+
+ bool isLDRD(const MCInst &Inst) const {
+ return (Inst.getOpcode() == AArch64::LDRDui ||
+ Inst.getOpcode() == AArch64::LDRDpre ||
+ Inst.getOpcode() == AArch64::LDRDpost ||
+ Inst.getOpcode() == AArch64::LDRDroW ||
+ Inst.getOpcode() == AArch64::LDRDroX);
+ }
+
+ bool isLDRQ(const MCInst &Inst) const {
+ return (Inst.getOpcode() == AArch64::LDRQui ||
+ Inst.getOpcode() == AArch64::LDRQpre ||
+ Inst.getOpcode() == AArch64::LDRQpost ||
+ Inst.getOpcode() == AArch64::LDRQroW ||
+ Inst.getOpcode() == AArch64::LDRQroX);
+ }
+
+ bool isLoadPair(const MCInst &Inst) const {
+ const unsigned opcode = Inst.getOpcode();
+
+ auto isLoadPairImmOffset = [&]() {
+ bool isLoadPair = false;
+ switch (opcode) {
+ case AArch64::LDPWi:
+ case AArch64::LDPXi:
+ case AArch64::LDPSi:
+ case AArch64::LDPSWi:
+ case AArch64::LDPDi:
+ case AArch64::LDPQi:
+ case AArch64::LDNPWi:
+ case AArch64::LDNPXi:
+ case AArch64::LDNPSi:
+ case AArch64::LDNPDi:
+ case AArch64::LDNPQi:
+ isLoadPair = true;
+ break;
+ default:
+ break;
+ }
+ return isLoadPair;
+ };
+
+ auto isLoadPairPostIndex = [&]() {
+ bool isLoadPair = false;
+ switch (opcode) {
+ case AArch64::LDPWpost:
+ case AArch64::LDPXpost:
+ case AArch64::LDPSpost:
+ case AArch64::LDPSWpost:
+ case AArch64::LDPDpost:
+ case AArch64::LDPQpost:
+ isLoadPair = true;
+ break;
+ default:
+ break;
+ }
+ return isLoadPair;
+ };
+
+ auto isLoadPairPreIndex = [&]() {
+ bool isLoadPair = false;
+ switch (opcode) {
+ case AArch64::LDPWpre:
+ case AArch64::LDPXpre:
+ case AArch64::LDPSpre:
+ case AArch64::LDPSWpre:
+ case AArch64::LDPDpre:
+ case AArch64::LDPQpre:
+ isLoadPair = true;
+ break;
+ default:
+ break;
+ }
+ return isLoadPair;
+ };
+
+ return isLoadPairImmOffset() || isLoadPairPostIndex() ||
+ isLoadPairPreIndex();
+ }
+
+ bool isLoadRegUnscaleImm(const MCInst &Inst) const {
+ const unsigned opcode = Inst.getOpcode();
+ bool isLoad = false;
+ switch (opcode) {
+ case AArch64::LDURBi:
+ case AArch64::LDURBBi:
+ case AArch64::LDURHi:
+ case AArch64::LDURHHi:
+ case AArch64::LDURWi:
+ case AArch64::LDURXi:
+ case AArch64::LDURSi:
+ case AArch64::LDURDi:
+ case AArch64::LDURQi:
+ case AArch64::LDURSBWi:
+ case AArch64::LDURSBXi:
+ case AArch64::LDURSHWi:
+ case AArch64::LDURSHXi:
+ case AArch64::LDURSWi:
+ isLoad = true;
+ break;
+ default:
+ break;
+ }
+ return isLoad;
+ }
+
+ bool isLoadRegUnscaleUnpriv(const MCInst &Inst) const {
+ const unsigned opcode = Inst.getOpcode();
+ bool isLoad = false;
+ switch (opcode) {
+ case AArch64::LDTRBi:
+ case AArch64::LDTRHi:
+ case AArch64::LDTRWi:
+ case AArch64::LDTRXi:
+ case AArch64::LDTRSBWi:
+ case AArch64::LDTRSHWi:
+ case AArch64::LDTRSBXi:
+ case AArch64::LDTRSHXi:
+ case AArch64::LDTRSWi:
+ isLoad = true;
+ break;
+ default:
+ break;
+ }
+ return isLoad;
+ }
+
bool mayLoad(const MCInst &Inst) const override {
- return isLDRB(Inst) || isLDRH(Inst) || isLDRW(Inst) || isLDRX(Inst);
+ return isLoadPair(Inst) || isLDRB(Inst) || isLDRH(Inst) || isLDRW(Inst) ||
+ isLDRX(Inst) || isLDRQ(Inst) || isLDRD(Inst) || isLDRS(Inst) ||
+ isLoadRegUnscaleImm(Inst) || isLoadRegUnscaleUnpriv(Inst) ||
+ isPrefetch(Inst);
}
bool isAArch64ExclusiveLoad(const MCInst &Inst) const override {
@@ -1140,7 +1300,248 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
Inst.addOperand(MCOperand::createImm(0));
}
- bool mayStore(const MCInst &Inst) const override { return false; }
+ bool isPrefetch(const MCInst &Inst) const {
+ const unsigned opcode = Inst.getOpcode();
+ bool isNeedle = false;
+ switch (opcode) {
+ case AArch64::PRFMl:
+ case AArch64::PRFMui:
+ case AArch64::PRFUMi:
+ case AArch64::PRFMroW:
+ case AArch64::PRFMroX:
+ isNeedle = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return isNeedle;
+ };
+
+ bool isStorePair(const MCInst &Inst) const {
+ const unsigned opcode = Inst.getOpcode();
+
+ auto isStorePairImmOffset = [&]() {
+ bool isStorePair = false;
+ switch (opcode) {
+ case AArch64::STPWi:
+ case AArch64::STPXi:
+ case AArch64::STPSi:
+ case AArch64::STPDi:
+ case AArch64::STPQi:
+ case AArch64::STNPWi:
+ case AArch64::STNPXi:
+ case AArch64::STNPSi:
+ case AArch64::STNPDi:
+ case AArch64::STNPQi:
+ isStorePair = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return isStorePair;
+ };
+
+ auto isStorePairPostIndex = [&]() {
+ bool isStorePair = false;
+ switch (opcode) {
+ case AArch64::STPWpost:
+ case AArch64::STPXpost:
+ case AArch64::STPSpost:
+ case AArch64::STPDpost:
+ case AArch64::STPQpost:
+ isStorePair = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return isStorePair;
+ };
+
+ auto isStorePairPreIndex = [&]() {
+ bool isStorePair = false;
+ switch (opcode) {
+ case AArch64::STPWpre:
+ case AArch64::STPXpre:
+ case AArch64::STPSpre:
+ case AArch64::STPDpre:
+ case AArch64::STPQpre:
+ isStorePair = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return isStorePair;
+ };
+
+ return isStorePairImmOffset() || isStorePairPostIndex() ||
+ isStorePairPreIndex();
+ }
+
+ bool isStoreReg(const MCInst &Inst) const {
+ const unsigned opcode = Inst.getOpcode();
+ bool isStore = false;
+
+ auto isStoreRegUnscaleImm = [&]() {
+ switch (opcode) {
+ case AArch64::STURBi:
+ case AArch64::STURBBi:
+ case AArch64::STURHi:
+ case AArch64::STURHHi:
+ case AArch64::STURWi:
+ case AArch64::STURXi:
+ case AArch64::STURSi:
+ case AArch64::STURDi:
+ case AArch64::STURQi:
+ isStore = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return isStore;
+ };
+
+ auto isStoreRegScaledImm = [&]() {
+ switch (opcode) {
+ case AArch64::STRBui:
+ case AArch64::STRBBui:
+ case AArch64::STRHui:
+ case AArch64::STRHHui:
+ case AArch64::STRWui:
+ case AArch64::STRXui:
+ case AArch64::STRSui:
+ case AArch64::STRDui:
+ case AArch64::STRQui:
+ isStore = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return isStore;
+ };
+
+ auto isStoreRegImmPostIndexed = [&]() {
+ switch (opcode) {
+ case AArch64::STRBpost:
+ case AArch64::STRBBpost:
+ case AArch64::STRHpost:
+ case AArch64::STRHHpost:
+ case AArch64::STRWpost:
+ case AArch64::STRXpost:
+ case AArch64::STRSpost:
+ case AArch64::STRDpost:
+ case AArch64::STRQpost:
+ isStore = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return isStore;
+ };
+
+ auto isStoreRegImmPreIndexed = [&]() {
+ switch (opcode) {
+ case AArch64::STRBpre:
+ case AArch64::STRBBpre:
+ case AArch64::STRHpre:
+ case AArch64::STRHHpre:
+ case AArch64::STRWpre:
+ case AArch64::STRXpre:
+ case AArch64::STRSpre:
+ case AArch64::STRDpre:
+ case AArch64::STRQpre:
+ isStore = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return isStore;
+ };
+
+ auto isStoreRegUnscaleUnpriv = [&]() {
+ switch (opcode) {
+ case AArch64::STTRBi:
+ case AArch64::STTRHi:
+ case AArch64::STTRWi:
+ case AArch64::STTRXi:
+ isStore = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return isStore;
+ };
+
+ auto isStoreRegTrunc = [&]() {
+ switch (opcode) {
+ case AArch64::STRBBroW:
+ case AArch64::STRBBroX:
+ case AArch64::STRBroW:
+ case AArch64::STRBroX:
+ case AArch64::STRDroW:
+ case AArch64::STRDroX:
+ case AArch64::STRHHroW:
+ case AArch64::STRHHroX:
+ case AArch64::STRHroW:
+ case AArch64::STRHroX:
+ case AArch64::STRQroW:
+ case AArch64::STRQroX:
+ case AArch64::STRSroW:
+ case AArch64::STRSroX:
+ case AArch64::STRWroW:
+ case AArch64::STRWroX:
+ case AArch64::STRXroW:
+ case AArch64::STRXroX:
+ isStore = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return isStore;
+ };
+
+ return isStoreRegUnscaleImm() || isStoreRegScaledImm() ||
+ isStoreRegImmPreIndexed() || isStoreRegImmPostIndexed() ||
+ isStoreRegUnscaleUnpriv() || isPrefetch(Inst) || isStoreRegTrunc();
+ }
+
+ bool mayStore(const MCInst &Inst) const override {
+ return isStorePair(Inst) || isStoreReg(Inst) ||
+ isAArch64ExclusiveStore(Inst);
+ }
+
+ bool isStoreToStack(const MCInst &Inst) const {
+ if (!mayStore(Inst))
+ return false;
+ for (const MCOperand &Operand : useOperands(Inst)) {
+ if (!Operand.isReg())
+ continue;
+ unsigned Reg = Operand.getReg();
+ if (Reg == AArch64::SP || Reg == AArch64::WSP || Reg == AArch64::FP ||
+ Reg == AArch64::W29)
+ return true;
+ }
+ return false;
+ }
void createDirectCall(MCInst &Inst, const MCSymbol *Target, MCContext *Ctx,
bool IsTailCall) override {
|
yota9
reviewed
Dec 20, 2024
Contributor
Author
|
@yota9 thanks, will check |
a84a836 to
60af14c
Compare
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
eac56f7 to
cfdd5e0
Compare
ayermolo
reviewed
Dec 20, 2024
cfdd5e0 to
e8dcd18
Compare
e8dcd18 to
5b614ec
Compare
yota9
reviewed
Jan 9, 2025
ae60c70 to
8e72ddc
Compare
yota9
reviewed
Jan 17, 2025
This functionality is needed for inliner pass and also for correct dyno stats.
6302f17 to
a09e0d8
Compare
yota9
approved these changes
Jan 17, 2025
Member
yota9
left a comment
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.
LGTM
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This functionality is needed for inliner pass and also for correct dyno stats.
Needed for PR