aboutsummaryrefslogtreecommitdiff
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.cpp108
1 files changed, 46 insertions, 62 deletions
diff --git a/lib/Target/AArch64/AArch64DeadRegisterDefinitionsPass.cpp b/lib/Target/AArch64/AArch64DeadRegisterDefinitionsPass.cpp
index 2ba10d25e939..a43077cb88ec 100644
--- a/lib/Target/AArch64/AArch64DeadRegisterDefinitionsPass.cpp
+++ b/lib/Target/AArch64/AArch64DeadRegisterDefinitionsPass.cpp
@@ -1,9 +1,8 @@
//==-- AArch64DeadRegisterDefinitions.cpp - Replace dead defs w/ zero reg --==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file When allowed by the instruction, replace a dead definition of a GPR
@@ -55,8 +54,6 @@ public:
AU.setPreservesCFG();
MachineFunctionPass::getAnalysisUsage(AU);
}
-
- bool shouldSkip(const MachineInstr &MI, const MachineFunction &MF) const;
};
char AArch64DeadRegisterDefinitions::ID = 0;
} // end anonymous namespace
@@ -71,60 +68,48 @@ 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;
- }
- }
+// Instructions that lose their 'read' operation for a subesquent fence acquire
+// (DMB LD) once the zero register is used.
+//
+// WARNING: The aquire variants of the instructions are also affected, but they
+// are split out into `atomicBarrierDroppedOnZero()` to support annotations on
+// assembly.
+static bool atomicReadDroppedOnZero(unsigned Opcode) {
+ switch (Opcode) {
+ case AArch64::LDADDB: case AArch64::LDADDH:
+ case AArch64::LDADDW: case AArch64::LDADDX:
+ case AArch64::LDADDLB: case AArch64::LDADDLH:
+ case AArch64::LDADDLW: case AArch64::LDADDLX:
+ case AArch64::LDCLRB: case AArch64::LDCLRH:
+ case AArch64::LDCLRW: case AArch64::LDCLRX:
+ case AArch64::LDCLRLB: case AArch64::LDCLRLH:
+ case AArch64::LDCLRLW: case AArch64::LDCLRLX:
+ case AArch64::LDEORB: case AArch64::LDEORH:
+ case AArch64::LDEORW: case AArch64::LDEORX:
+ case AArch64::LDEORLB: case AArch64::LDEORLH:
+ case AArch64::LDEORLW: case AArch64::LDEORLX:
+ case AArch64::LDSETB: case AArch64::LDSETH:
+ case AArch64::LDSETW: case AArch64::LDSETX:
+ case AArch64::LDSETLB: case AArch64::LDSETLH:
+ case AArch64::LDSETLW: case AArch64::LDSETLX:
+ case AArch64::LDSMAXB: case AArch64::LDSMAXH:
+ case AArch64::LDSMAXW: case AArch64::LDSMAXX:
+ case AArch64::LDSMAXLB: case AArch64::LDSMAXLH:
+ case AArch64::LDSMAXLW: case AArch64::LDSMAXLX:
+ case AArch64::LDSMINB: case AArch64::LDSMINH:
+ case AArch64::LDSMINW: case AArch64::LDSMINX:
+ case AArch64::LDSMINLB: case AArch64::LDSMINLH:
+ case AArch64::LDSMINLW: case AArch64::LDSMINLX:
+ case AArch64::LDUMAXB: case AArch64::LDUMAXH:
+ case AArch64::LDUMAXW: case AArch64::LDUMAXX:
+ case AArch64::LDUMAXLB: case AArch64::LDUMAXLH:
+ case AArch64::LDUMAXLW: case AArch64::LDUMAXLX:
+ case AArch64::LDUMINB: case AArch64::LDUMINH:
+ case AArch64::LDUMINW: case AArch64::LDUMINX:
+ case AArch64::LDUMINLB: case AArch64::LDUMINLH:
+ case AArch64::LDUMINLW: case AArch64::LDUMINLX:
+ return true;
}
-
-#undef CASE_AARCH64_ATOMIC_
-
return false;
}
@@ -148,9 +133,8 @@ void AArch64DeadRegisterDefinitions::processMachineBasicBlock(
continue;
}
- if (shouldSkip(MI, MF)) {
- LLVM_DEBUG(dbgs() << " Ignoring, Atomic instruction with acquire "
- "semantics using WZR/XZR\n");
+ if (atomicBarrierDroppedOnZero(MI.getOpcode()) || atomicReadDroppedOnZero(MI.getOpcode())) {
+ LLVM_DEBUG(dbgs() << " Ignoring, semantics change with xzr/wzr.\n");
continue;
}