[llvm] [BOLT][AArch64] Add isPush & isPop (PR #120713)
Alexey Moksyakov via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 17 03:18:50 PST 2025
https://github.com/yavtuk updated https://github.com/llvm/llvm-project/pull/120713
>From 8e72ddc46bc7a7002e01a1cd89258a7c7b117cec 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 | 445 ++++++++++++++++--
1 file changed, 403 insertions(+), 42 deletions(-)
diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
index 679c9774c767f7..6d266fc7df7866 100644
--- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
+++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
@@ -133,6 +133,16 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
public:
using MCPlusBuilder::MCPlusBuilder;
+ MCPhysReg getFramePointer() const override { return AArch64::FP; }
+
+ 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,59 +224,207 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
}
bool isLDRB(const MCInst &Inst) const {
- return (Inst.getOpcode() == AArch64::LDRBBpost ||
- Inst.getOpcode() == AArch64::LDRBBpre ||
- Inst.getOpcode() == AArch64::LDRBBroW ||
- Inst.getOpcode() == AArch64::LDRBBroX ||
- Inst.getOpcode() == AArch64::LDRBBui ||
- Inst.getOpcode() == AArch64::LDRSBWpost ||
- Inst.getOpcode() == AArch64::LDRSBWpre ||
- Inst.getOpcode() == AArch64::LDRSBWroW ||
- Inst.getOpcode() == AArch64::LDRSBWroX ||
- Inst.getOpcode() == AArch64::LDRSBWui ||
- Inst.getOpcode() == AArch64::LDRSBXpost ||
- Inst.getOpcode() == AArch64::LDRSBXpre ||
- Inst.getOpcode() == AArch64::LDRSBXroW ||
- Inst.getOpcode() == AArch64::LDRSBXroX ||
- Inst.getOpcode() == AArch64::LDRSBXui);
+ const unsigned opcode = Inst.getOpcode();
+ switch (opcode) {
+ case AArch64::LDRBpost:
+ case AArch64::LDRBBpost:
+ case AArch64::LDRBBpre:
+ case AArch64::LDRBBroW:
+ case AArch64::LDRBroW:
+ case AArch64::LDRBroX:
+ case AArch64::LDRBBroX:
+ case AArch64::LDRBBui:
+ case AArch64::LDRBui:
+ case AArch64::LDRBpre:
+ case AArch64::LDRSBWpost:
+ case AArch64::LDRSBWpre:
+ case AArch64::LDRSBWroW:
+ case AArch64::LDRSBWroX:
+ case AArch64::LDRSBWui:
+ case AArch64::LDRSBXpost:
+ case AArch64::LDRSBXpre:
+ case AArch64::LDRSBXroW:
+ case AArch64::LDRSBXroX:
+ case AArch64::LDRSBXui:
+ case AArch64::LDURBi:
+ case AArch64::LDURBBi:
+ case AArch64::LDURSBWi:
+ case AArch64::LDURSBXi:
+ case AArch64::LDTRBi:
+ case AArch64::LDTRSBWi:
+ case AArch64::LDTRSBXi:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
}
bool isLDRH(const MCInst &Inst) const {
- return (Inst.getOpcode() == AArch64::LDRHHpost ||
- Inst.getOpcode() == AArch64::LDRHHpre ||
- Inst.getOpcode() == AArch64::LDRHHroW ||
- Inst.getOpcode() == AArch64::LDRHHroX ||
- Inst.getOpcode() == AArch64::LDRHHui ||
- Inst.getOpcode() == AArch64::LDRSHWpost ||
- Inst.getOpcode() == AArch64::LDRSHWpre ||
- Inst.getOpcode() == AArch64::LDRSHWroW ||
- Inst.getOpcode() == AArch64::LDRSHWroX ||
- Inst.getOpcode() == AArch64::LDRSHWui ||
- Inst.getOpcode() == AArch64::LDRSHXpost ||
- Inst.getOpcode() == AArch64::LDRSHXpre ||
- Inst.getOpcode() == AArch64::LDRSHXroW ||
- Inst.getOpcode() == AArch64::LDRSHXroX ||
- Inst.getOpcode() == AArch64::LDRSHXui);
+ const unsigned opcode = Inst.getOpcode();
+ switch (opcode) {
+ case AArch64::LDRHpost:
+ case AArch64::LDRHHpost:
+ case AArch64::LDRHHpre:
+ case AArch64::LDRHroW:
+ case AArch64::LDRHHroW:
+ case AArch64::LDRHroX:
+ case AArch64::LDRHHroX:
+ case AArch64::LDRHHui:
+ case AArch64::LDRHui:
+ case AArch64::LDRHpre:
+ case AArch64::LDRSHWpost:
+ case AArch64::LDRSHWpre:
+ case AArch64::LDRSHWroW:
+ case AArch64::LDRSHWroX:
+ case AArch64::LDRSHWui:
+ case AArch64::LDRSHXpost:
+ case AArch64::LDRSHXpre:
+ case AArch64::LDRSHXroW:
+ case AArch64::LDRSHXroX:
+ case AArch64::LDRSHXui:
+ case AArch64::LDURHi:
+ case AArch64::LDURHHi:
+ case AArch64::LDURSHWi:
+ case AArch64::LDURSHXi:
+ case AArch64::LDTRHi:
+ case AArch64::LDTRSHWi:
+ case AArch64::LDTRSHXi:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
}
bool isLDRW(const MCInst &Inst) const {
- return (Inst.getOpcode() == AArch64::LDRWpost ||
- Inst.getOpcode() == AArch64::LDRWpre ||
- Inst.getOpcode() == AArch64::LDRWroW ||
- Inst.getOpcode() == AArch64::LDRWroX ||
- Inst.getOpcode() == AArch64::LDRWui);
+ const unsigned opcode = Inst.getOpcode();
+ switch (opcode) {
+ case AArch64::LDRWpost:
+ case AArch64::LDRWpre:
+ case AArch64::LDRWroW:
+ case AArch64::LDRWroX:
+ case AArch64::LDRWui:
+ case AArch64::LDRWl:
+ case AArch64::LDRSWl:
+ case AArch64::LDURWi:
+ case AArch64::LDRSWpost:
+ case AArch64::LDRSWpre:
+ case AArch64::LDRSWroW:
+ case AArch64::LDRSWroX:
+ case AArch64::LDRSWui:
+ case AArch64::LDURSWi:
+ case AArch64::LDTRWi:
+ case AArch64::LDTRSWi:
+ case AArch64::LDPWi:
+ case AArch64::LDPWpost:
+ case AArch64::LDPWpre:
+ case AArch64::LDPSWi:
+ case AArch64::LDPSWpost:
+ case AArch64::LDPSWpre:
+ case AArch64::LDNPWi:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
}
bool isLDRX(const MCInst &Inst) const {
- return (Inst.getOpcode() == AArch64::LDRXpost ||
- Inst.getOpcode() == AArch64::LDRXpre ||
- Inst.getOpcode() == AArch64::LDRXroW ||
- Inst.getOpcode() == AArch64::LDRXroX ||
- Inst.getOpcode() == AArch64::LDRXui);
+ const unsigned opcode = Inst.getOpcode();
+ switch (opcode) {
+ case AArch64::LDRXpost:
+ case AArch64::LDRXpre:
+ case AArch64::LDRXroW:
+ case AArch64::LDRXroX:
+ case AArch64::LDRXui:
+ case AArch64::LDRXl:
+ case AArch64::LDURXi:
+ case AArch64::LDTRXi:
+ case AArch64::LDNPXi:
+ case AArch64::LDPXi:
+ case AArch64::LDPXpost:
+ case AArch64::LDPXpre:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ }
+
+ bool isLDRS(const MCInst &Inst) const {
+ const unsigned opcode = Inst.getOpcode();
+ switch (opcode) {
+ case AArch64::LDRSl:
+ case AArch64::LDRSui:
+ case AArch64::LDRSroW:
+ case AArch64::LDRSroX:
+ case AArch64::LDURSi:
+ case AArch64::LDPSi:
+ case AArch64::LDNPSi:
+ case AArch64::LDRSpre:
+ case AArch64::LDRSpost:
+ case AArch64::LDPSpost:
+ case AArch64::LDPSpre:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ }
+
+ bool isLDRD(const MCInst &Inst) const {
+ const unsigned opcode = Inst.getOpcode();
+ switch (opcode) {
+ case AArch64::LDRDl:
+ case AArch64::LDRDui:
+ case AArch64::LDRDpre:
+ case AArch64::LDRDpost:
+ case AArch64::LDRDroW:
+ case AArch64::LDRDroX:
+ case AArch64::LDURDi:
+ case AArch64::LDPDi:
+ case AArch64::LDNPDi:
+ case AArch64::LDPDpost:
+ case AArch64::LDPDpre:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ }
+
+ bool isLDRQ(const MCInst &Inst) const {
+ const unsigned opcode = Inst.getOpcode();
+ switch (opcode) {
+ case AArch64::LDRQui:
+ case AArch64::LDRQl:
+ case AArch64::LDRQpre:
+ case AArch64::LDRQpost:
+ case AArch64::LDRQroW:
+ case AArch64::LDRQroX:
+ case AArch64::LDURQi:
+ case AArch64::LDPQi:
+ case AArch64::LDNPQi:
+ case AArch64::LDPQpost:
+ case AArch64::LDPQpre:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
}
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);
}
bool isAArch64ExclusiveLoad(const MCInst &Inst) const override {
@@ -1140,7 +1298,210 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
Inst.addOperand(MCOperand::createImm(0));
}
- bool mayStore(const MCInst &Inst) const override { return false; }
+ bool isStorePair(const MCInst &Inst) const {
+ const unsigned opcode = Inst.getOpcode();
+
+ auto isStorePairImmOffset = [&]() {
+ 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:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ };
+
+ auto isStorePairPostIndex = [&]() {
+ switch (opcode) {
+ case AArch64::STPWpost:
+ case AArch64::STPXpost:
+ case AArch64::STPSpost:
+ case AArch64::STPDpost:
+ case AArch64::STPQpost:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ };
+
+ auto isStorePairPreIndex = [&]() {
+ switch (opcode) {
+ case AArch64::STPWpre:
+ case AArch64::STPXpre:
+ case AArch64::STPSpre:
+ case AArch64::STPDpre:
+ case AArch64::STPQpre:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ };
+
+ return isStorePairImmOffset() || isStorePairPostIndex() ||
+ isStorePairPreIndex();
+ }
+
+ bool isStoreReg(const MCInst &Inst) const {
+ const unsigned opcode = Inst.getOpcode();
+
+ 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:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ };
+
+ 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:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ };
+
+ 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:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ };
+
+ 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:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ };
+
+ auto isStoreRegUnscaleUnpriv = [&]() {
+ switch (opcode) {
+ case AArch64::STTRBi:
+ case AArch64::STTRHi:
+ case AArch64::STTRWi:
+ case AArch64::STTRXi:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ };
+
+ 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:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ };
+
+ return isStoreRegUnscaleImm() || isStoreRegScaledImm() ||
+ isStoreRegImmPreIndexed() || isStoreRegImmPostIndexed() ||
+ isStoreRegUnscaleUnpriv() || 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