LLVM: lib/Target/AArch64/AArch64DeadRegisterDefinitionsPass.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
25using namespace llvm;
26
27#define DEBUG_TYPE "aarch64-dead-defs"
28
29STATISTIC(NumDeadDefsReplaced, "Number of dead definitions replaced");
30
31#define AARCH64_DEAD_REG_DEF_NAME "AArch64 Dead register definitions"
32
33namespace {
35private:
41public:
42 static char ID;
44
46
48
49 void getAnalysisUsage(AnalysisUsage &AU) const override {
52 }
53};
54char AArch64DeadRegisterDefinitions::ID = 0;
55}
56
57INITIALIZE_PASS(AArch64DeadRegisterDefinitions, "aarch64-dead-defs",
59
62 if (MO.isFI())
63 return true;
64 return false;
65}
66
67
68
69
70
71
72
74 switch (Opcode) {
75 case AArch64::LDADDB: case AArch64::LDADDH:
76 case AArch64::LDADDW: case AArch64::LDADDX:
77 case AArch64::LDADDLB: case AArch64::LDADDLH:
78 case AArch64::LDADDLW: case AArch64::LDADDLX:
79 case AArch64::LDCLRB: case AArch64::LDCLRH:
80 case AArch64::LDCLRW: case AArch64::LDCLRX:
81 case AArch64::LDCLRLB: case AArch64::LDCLRLH:
82 case AArch64::LDCLRLW: case AArch64::LDCLRLX:
83 case AArch64::LDEORB: case AArch64::LDEORH:
84 case AArch64::LDEORW: case AArch64::LDEORX:
85 case AArch64::LDEORLB: case AArch64::LDEORLH:
86 case AArch64::LDEORLW: case AArch64::LDEORLX:
87 case AArch64::LDSETB: case AArch64::LDSETH:
88 case AArch64::LDSETW: case AArch64::LDSETX:
89 case AArch64::LDSETLB: case AArch64::LDSETLH:
90 case AArch64::LDSETLW: case AArch64::LDSETLX:
91 case AArch64::LDSMAXB: case AArch64::LDSMAXH:
92 case AArch64::LDSMAXW: case AArch64::LDSMAXX:
93 case AArch64::LDSMAXLB: case AArch64::LDSMAXLH:
94 case AArch64::LDSMAXLW: case AArch64::LDSMAXLX:
95 case AArch64::LDSMINB: case AArch64::LDSMINH:
96 case AArch64::LDSMINW: case AArch64::LDSMINX:
97 case AArch64::LDSMINLB: case AArch64::LDSMINLH:
98 case AArch64::LDSMINLW: case AArch64::LDSMINLX:
99 case AArch64::LDUMAXB: case AArch64::LDUMAXH:
100 case AArch64::LDUMAXW: case AArch64::LDUMAXX:
101 case AArch64::LDUMAXLB: case AArch64::LDUMAXLH:
102 case AArch64::LDUMAXLW: case AArch64::LDUMAXLX:
103 case AArch64::LDUMINB: case AArch64::LDUMINH:
104 case AArch64::LDUMINW: case AArch64::LDUMINX:
105 case AArch64::LDUMINLB: case AArch64::LDUMINLH:
106 case AArch64::LDUMINLW: case AArch64::LDUMINLX:
107 case AArch64::SWPB: case AArch64::SWPH:
108 case AArch64::SWPW: case AArch64::SWPX:
109 case AArch64::SWPLB: case AArch64::SWPLH:
110 case AArch64::SWPLW: case AArch64::SWPLX:
111 return true;
112 }
113 return false;
114}
115
116void AArch64DeadRegisterDefinitions::processMachineBasicBlock(
118 for (MachineInstr &MI : MBB) {
119 if (usesFrameIndex(MI)) {
120
121
122
123 LLVM_DEBUG(dbgs() << " Ignoring, operand is frame index\n");
124 continue;
125 }
126 if (MI.definesRegister(AArch64::XZR, nullptr) ||
127 MI.definesRegister(AArch64::WZR, nullptr)) {
128
129
132 << " Ignoring, XZR or WZR already used by the instruction\n");
133 continue;
134 }
135
137 LLVM_DEBUG(dbgs() << " Ignoring, semantics change with xzr/wzr.\n");
138 continue;
139 }
140
141 const MCInstrDesc &Desc = MI.getDesc();
142 for (int I = 0, E = Desc.getNumDefs(); I != E; ++I) {
143 MachineOperand &MO = MI.getOperand(I);
145 continue;
146
147
150 continue;
152 LLVM_DEBUG(dbgs() << " Dead def operand #" << I << " in:\n ";
154
155 if (MI.isRegTiedToUseOperand(I)) {
156 LLVM_DEBUG(dbgs() << " Ignoring, def is tied operand.\n");
157 continue;
158 }
160 unsigned NewReg;
161 if (RC == nullptr) {
162 LLVM_DEBUG(dbgs() << " Ignoring, register is not a GPR.\n");
163 continue;
164 } else if (RC->contains(AArch64::WZR))
165 NewReg = AArch64::WZR;
166 else if (RC->contains(AArch64::XZR))
167 NewReg = AArch64::XZR;
168 else {
169 LLVM_DEBUG(dbgs() << " Ignoring, register is not a GPR.\n");
170 continue;
171 }
172 LLVM_DEBUG(dbgs() << " Replacing with zero register. New:\n ");
176 ++NumDeadDefsReplaced;
178
179 break;
180 }
181 }
182}
183
184
185
186bool AArch64DeadRegisterDefinitions::runOnMachineFunction(MachineFunction &MF) {
188 return false;
189
193 LLVM_DEBUG(dbgs() << "***** AArch64DeadRegisterDefinitions *****\n");
195 for (auto &MBB : MF)
196 processMachineBasicBlock(MBB);
198}
199
201 return new AArch64DeadRegisterDefinitions();
202}
unsigned const MachineRegisterInfo * MRI
static bool atomicReadDroppedOnZero(unsigned Opcode)
Definition AArch64DeadRegisterDefinitionsPass.cpp:73
#define AARCH64_DEAD_REG_DEF_NAME
Definition AArch64DeadRegisterDefinitionsPass.cpp:31
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Represent the analysis usage information of a pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
FunctionPass class - This class is used to implement most global optimizations.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void setIsDead(bool Val=true)
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
virtual void print(raw_ostream &OS, const Module *M) const
print - Print out the internal state of the pass.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
StringRef - Represent a constant reference to a string, i.e.
TargetInstrInfo - Interface to description of machine instruction set.
virtual const TargetRegisterClass * getRegClass(const MCInstrDesc &MCID, unsigned OpNum) const
Given a machine instruction descriptor, returns the register class constraint for OpNum,...
bool contains(Register Reg) const
Return true if the specified register is included in this register class.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createAArch64DeadRegisterDefinitions()
Definition AArch64DeadRegisterDefinitionsPass.cpp:200
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static bool atomicBarrierDroppedOnZero(unsigned Opcode)