[llvm] [BOLT][AArch64] Add isPush & isPop (PR #120713)
Alexey Moksyakov via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 20 04:46:21 PST 2024
https://github.com/yavtuk updated https://github.com/llvm/llvm-project/pull/120713
>From 60af14ca3b76d6891d871a6b9347463c38d1b52e Mon Sep 17 00:00:00 2001
From: Moksyakov Alexey <yavtuk at yandex.ru>
Date: Fri, 20 Dec 2024 09:18:41 +0000
Subject: [PATCH] [BOLT][Aarch64] Add isPush & isPop checking
This functionality is needed for inliner pass and also
for correct dyno stats.
---
.../Target/AArch64/AArch64MCPlusBuilder.cpp | 354 +++++++++++++++++-
1 file changed, 346 insertions(+), 8 deletions(-)
diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
index 7e08e5c81d26ff..4da40bccaff384 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 ||
@@ -228,15 +241,27 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
Inst.getOpcode() == AArch64::LDRSBXpre ||
Inst.getOpcode() == AArch64::LDRSBXroW ||
Inst.getOpcode() == AArch64::LDRSBXroX ||
- Inst.getOpcode() == AArch64::LDRSBXui);
+ Inst.getOpcode() == AArch64::LDRSBXui ||
+ Inst.getOpcode() == AArch64::LDURBi ||
+ Inst.getOpcode() == AArch64::LDURBBi ||
+ Inst.getOpcode() == AArch64::LDURSBWi ||
+ Inst.getOpcode() == AArch64::LDURSBXi ||
+ Inst.getOpcode() == AArch64::LDTRBi ||
+ Inst.getOpcode() == AArch64::LDTRSBWi ||
+ Inst.getOpcode() == AArch64::LDTRSBXi);
}
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 ||
@@ -246,7 +271,14 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
Inst.getOpcode() == AArch64::LDRSHXpre ||
Inst.getOpcode() == AArch64::LDRSHXroW ||
Inst.getOpcode() == AArch64::LDRSHXroX ||
- Inst.getOpcode() == AArch64::LDRSHXui);
+ Inst.getOpcode() == AArch64::LDRSHXui ||
+ Inst.getOpcode() == AArch64::LDURHi ||
+ Inst.getOpcode() == AArch64::LDURHHi ||
+ Inst.getOpcode() == AArch64::LDURSHWi ||
+ Inst.getOpcode() == AArch64::LDURSHXi ||
+ Inst.getOpcode() == AArch64::LDTRHi ||
+ Inst.getOpcode() == AArch64::LDTRSHWi ||
+ Inst.getOpcode() == AArch64::LDTRSHXi);
}
bool isLDRW(const MCInst &Inst) const {
@@ -254,7 +286,23 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
Inst.getOpcode() == AArch64::LDRWpre ||
Inst.getOpcode() == AArch64::LDRWroW ||
Inst.getOpcode() == AArch64::LDRWroX ||
- Inst.getOpcode() == AArch64::LDRWui);
+ Inst.getOpcode() == AArch64::LDRWui ||
+ Inst.getOpcode() == AArch64::LDURWi ||
+ Inst.getOpcode() == AArch64::LDRSWpost ||
+ Inst.getOpcode() == AArch64::LDRSWpre ||
+ Inst.getOpcode() == AArch64::LDRSWroW ||
+ Inst.getOpcode() == AArch64::LDRSWroX ||
+ Inst.getOpcode() == AArch64::LDRSWui ||
+ Inst.getOpcode() == AArch64::LDURSWi ||
+ Inst.getOpcode() == AArch64::LDTRWi ||
+ Inst.getOpcode() == AArch64::LDTRSWi ||
+ Inst.getOpcode() == AArch64::LDPWi ||
+ Inst.getOpcode() == AArch64::LDPWpost ||
+ Inst.getOpcode() == AArch64::LDPWpre ||
+ Inst.getOpcode() == AArch64::LDPSWi ||
+ Inst.getOpcode() == AArch64::LDPSWpost ||
+ Inst.getOpcode() == AArch64::LDPSWpre ||
+ Inst.getOpcode() == AArch64::LDNPWi);
}
bool isLDRX(const MCInst &Inst) const {
@@ -262,11 +310,60 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
Inst.getOpcode() == AArch64::LDRXpre ||
Inst.getOpcode() == AArch64::LDRXroW ||
Inst.getOpcode() == AArch64::LDRXroX ||
- Inst.getOpcode() == AArch64::LDRXui);
+ Inst.getOpcode() == AArch64::LDRXui ||
+ Inst.getOpcode() == AArch64::LDURXi ||
+ Inst.getOpcode() == AArch64::LDTRXi ||
+ Inst.getOpcode() == AArch64::LDNPXi ||
+ Inst.getOpcode() == AArch64::LDPXi ||
+ Inst.getOpcode() == AArch64::LDPXpost ||
+ Inst.getOpcode() == AArch64::LDPXpre ||
+ Inst.getOpcode() == AArch64::LDNPXi);
+ }
+
+
+ bool isLDRS(const MCInst &Inst) const {
+ return (Inst.getOpcode() == AArch64::LDRSui ||
+ Inst.getOpcode() == AArch64::LDRSroW ||
+ Inst.getOpcode() == AArch64::LDRSroX ||
+ Inst.getOpcode() == AArch64::LDURSi ||
+ Inst.getOpcode() == AArch64::LDPSi ||
+ Inst.getOpcode() == AArch64::LDNPSi ||
+ Inst.getOpcode() == AArch64::LDRSpre ||
+ Inst.getOpcode() == AArch64::LDRSpost ||
+ Inst.getOpcode() == AArch64::LDPSpost ||
+ Inst.getOpcode() == AArch64::LDPSpre);
+ }
+
+ 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 ||
+ Inst.getOpcode() == AArch64::LDURDi ||
+ Inst.getOpcode() == AArch64::LDPDi ||
+ Inst.getOpcode() == AArch64::LDNPDi ||
+ Inst.getOpcode() == AArch64::LDPDpost ||
+ Inst.getOpcode() == AArch64::LDPDpre);
+ }
+
+ 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 ||
+ Inst.getOpcode() == AArch64::LDURQi ||
+ Inst.getOpcode() == AArch64::LDPQi ||
+ Inst.getOpcode() == AArch64::LDNPQi ||
+ Inst.getOpcode() == AArch64::LDPQpost ||
+ Inst.getOpcode() == AArch64::LDPQpre);
}
bool mayLoad(const MCInst &Inst) const override {
- return isLDRB(Inst) || isLDRH(Inst) || isLDRW(Inst) || isLDRX(Inst);
+ return isLDRB(Inst) || isLDRH(Inst) || isLDRW(Inst) ||
+ isLDRX(Inst) || isLDRQ(Inst) || isLDRD(Inst) ||
+ isLDRS(Inst) || isPrefetch(Inst);
}
bool isAArch64ExclusiveLoad(const MCInst &Inst) const override {
@@ -1140,7 +1237,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 {
More information about the llvm-commits
mailing list