summaryrefslogtreecommitdiff
path: root/lib/Target/AArch64/AArch64DeadRegisterDefinitionsPass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/AArch64/AArch64DeadRegisterDefinitionsPass.cpp')
-rw-r--r--lib/Target/AArch64/AArch64DeadRegisterDefinitionsPass.cpp118
1 files changed, 67 insertions, 51 deletions
diff --git a/lib/Target/AArch64/AArch64DeadRegisterDefinitionsPass.cpp b/lib/Target/AArch64/AArch64DeadRegisterDefinitionsPass.cpp
index b72f23b109d9..8e7e740da6f6 100644
--- a/lib/Target/AArch64/AArch64DeadRegisterDefinitionsPass.cpp
+++ b/lib/Target/AArch64/AArch64DeadRegisterDefinitionsPass.cpp
@@ -20,10 +20,10 @@
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
using namespace llvm;
#define DEBUG_TYPE "aarch64-dead-defs"
@@ -55,6 +55,8 @@ public:
AU.setPreservesCFG();
MachineFunctionPass::getAnalysisUsage(AU);
}
+
+ bool shouldSkip(const MachineInstr &MI, const MachineFunction &MF) const;
};
char AArch64DeadRegisterDefinitions::ID = 0;
} // end anonymous namespace
@@ -69,6 +71,63 @@ static bool usesFrameIndex(const MachineInstr &MI) {
return false;
}
+bool
+AArch64DeadRegisterDefinitions::shouldSkip(const MachineInstr &MI,
+ const MachineFunction &MF) const {
+ if (!MF.getSubtarget<AArch64Subtarget>().hasLSE())
+ return false;
+
+#define CASE_AARCH64_ATOMIC_(PREFIX) \
+ case AArch64::PREFIX##X: \
+ case AArch64::PREFIX##W: \
+ case AArch64::PREFIX##H: \
+ case AArch64::PREFIX##B
+
+ for (const MachineMemOperand *MMO : MI.memoperands()) {
+ if (MMO->isAtomic()) {
+ unsigned Opcode = MI.getOpcode();
+ switch (Opcode) {
+ default:
+ return false;
+ break;
+
+ CASE_AARCH64_ATOMIC_(LDADDA):
+ CASE_AARCH64_ATOMIC_(LDADDAL):
+
+ CASE_AARCH64_ATOMIC_(LDCLRA):
+ CASE_AARCH64_ATOMIC_(LDCLRAL):
+
+ CASE_AARCH64_ATOMIC_(LDEORA):
+ CASE_AARCH64_ATOMIC_(LDEORAL):
+
+ CASE_AARCH64_ATOMIC_(LDSETA):
+ CASE_AARCH64_ATOMIC_(LDSETAL):
+
+ CASE_AARCH64_ATOMIC_(LDSMAXA):
+ CASE_AARCH64_ATOMIC_(LDSMAXAL):
+
+ CASE_AARCH64_ATOMIC_(LDSMINA):
+ CASE_AARCH64_ATOMIC_(LDSMINAL):
+
+ CASE_AARCH64_ATOMIC_(LDUMAXA):
+ CASE_AARCH64_ATOMIC_(LDUMAXAL):
+
+ CASE_AARCH64_ATOMIC_(LDUMINA):
+ CASE_AARCH64_ATOMIC_(LDUMINAL):
+
+ CASE_AARCH64_ATOMIC_(SWPA):
+ CASE_AARCH64_ATOMIC_(SWPAL):
+ return true;
+ break;
+ }
+ }
+ }
+
+#undef CASE_AARCH64_ATOMIC_
+
+ return false;
+}
+
void AArch64DeadRegisterDefinitions::processMachineBasicBlock(
MachineBasicBlock &MBB) {
const MachineFunction &MF = *MBB.getParent();
@@ -86,55 +145,12 @@ void AArch64DeadRegisterDefinitions::processMachineBasicBlock(
DEBUG(dbgs() << " Ignoring, XZR or WZR already used by the instruction\n");
continue;
}
- if (MF.getSubtarget<AArch64Subtarget>().hasLSE()) {
- // XZ/WZ for LSE can only be used when acquire semantics are not used,
- // LDOPAL WZ is an invalid opcode.
- switch (MI.getOpcode()) {
- case AArch64::CASALb:
- case AArch64::CASALh:
- case AArch64::CASALs:
- case AArch64::CASALd:
- case AArch64::SWPALb:
- case AArch64::SWPALh:
- case AArch64::SWPALs:
- case AArch64::SWPALd:
- case AArch64::LDADDALb:
- case AArch64::LDADDALh:
- case AArch64::LDADDALs:
- case AArch64::LDADDALd:
- case AArch64::LDCLRALb:
- case AArch64::LDCLRALh:
- case AArch64::LDCLRALs:
- case AArch64::LDCLRALd:
- case AArch64::LDEORALb:
- case AArch64::LDEORALh:
- case AArch64::LDEORALs:
- case AArch64::LDEORALd:
- case AArch64::LDSETALb:
- case AArch64::LDSETALh:
- case AArch64::LDSETALs:
- case AArch64::LDSETALd:
- case AArch64::LDSMINALb:
- case AArch64::LDSMINALh:
- case AArch64::LDSMINALs:
- case AArch64::LDSMINALd:
- case AArch64::LDSMAXALb:
- case AArch64::LDSMAXALh:
- case AArch64::LDSMAXALs:
- case AArch64::LDSMAXALd:
- case AArch64::LDUMINALb:
- case AArch64::LDUMINALh:
- case AArch64::LDUMINALs:
- case AArch64::LDUMINALd:
- case AArch64::LDUMAXALb:
- case AArch64::LDUMAXALh:
- case AArch64::LDUMAXALs:
- case AArch64::LDUMAXALd:
- continue;
- default:
- break;
- }
+
+ if (shouldSkip(MI, MF)) {
+ DEBUG(dbgs() << " Ignoring, Atomic instruction with acquire semantics using WZR/XZR\n");
+ continue;
}
+
const MCInstrDesc &Desc = MI.getDesc();
for (int I = 0, E = Desc.getNumDefs(); I != E; ++I) {
MachineOperand &MO = MI.getOperand(I);
@@ -182,7 +198,7 @@ void AArch64DeadRegisterDefinitions::processMachineBasicBlock(
// Scan the function for instructions that have a dead definition of a
// register. Replace that register with the zero register when possible.
bool AArch64DeadRegisterDefinitions::runOnMachineFunction(MachineFunction &MF) {
- if (skipFunction(*MF.getFunction()))
+ if (skipFunction(MF.getFunction()))
return false;
TRI = MF.getSubtarget().getRegisterInfo();