Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/AArch64/AArch64DeadRegisterDefinitionsPass.cpp
Line
Count
Source (jump to first uncovered line)
1
//==-- AArch64DeadRegisterDefinitions.cpp - Replace dead defs w/ zero reg --==//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
/// \file When allowed by the instruction, replace a dead definition of a GPR
10
/// with the zero register. This makes the code a bit friendlier towards the
11
/// hardware's register renamer.
12
//===----------------------------------------------------------------------===//
13
14
#include "AArch64.h"
15
#include "AArch64RegisterInfo.h"
16
#include "AArch64Subtarget.h"
17
#include "llvm/ADT/Statistic.h"
18
#include "llvm/CodeGen/ISDOpcodes.h"
19
#include "llvm/CodeGen/MachineFunction.h"
20
#include "llvm/CodeGen/MachineFunctionPass.h"
21
#include "llvm/CodeGen/MachineInstr.h"
22
#include "llvm/CodeGen/MachineRegisterInfo.h"
23
#include "llvm/Support/Debug.h"
24
#include "llvm/Support/raw_ostream.h"
25
#include "llvm/Target/TargetInstrInfo.h"
26
#include "llvm/Target/TargetSubtargetInfo.h"
27
using namespace llvm;
28
29
#define DEBUG_TYPE "aarch64-dead-defs"
30
31
STATISTIC(NumDeadDefsReplaced, "Number of dead definitions replaced");
32
33
13.7k
#define AARCH64_DEAD_REG_DEF_NAME "AArch64 Dead register definitions"
34
35
namespace {
36
class AArch64DeadRegisterDefinitions : public MachineFunctionPass {
37
private:
38
  const TargetRegisterInfo *TRI;
39
  const MachineRegisterInfo *MRI;
40
  const TargetInstrInfo *TII;
41
  bool Changed;
42
  void processMachineBasicBlock(MachineBasicBlock &MBB);
43
public:
44
  static char ID; // Pass identification, replacement for typeid.
45
13.8k
  AArch64DeadRegisterDefinitions() : MachineFunctionPass(ID) {
46
13.8k
    initializeAArch64DeadRegisterDefinitionsPass(
47
13.8k
        *PassRegistry::getPassRegistry());
48
13.8k
  }
49
50
  bool runOnMachineFunction(MachineFunction &F) override;
51
52
13.7k
  StringRef getPassName() const override 
{ return 13.7k
AARCH64_DEAD_REG_DEF_NAME13.7k
; }
53
54
13.7k
  void getAnalysisUsage(AnalysisUsage &AU) const override {
55
13.7k
    AU.setPreservesCFG();
56
13.7k
    MachineFunctionPass::getAnalysisUsage(AU);
57
13.7k
  }
58
59
  bool shouldSkip(const MachineInstr &MI, const MachineFunction &MF) const;
60
};
61
char AArch64DeadRegisterDefinitions::ID = 0;
62
} // end anonymous namespace
63
64
INITIALIZE_PASS(AArch64DeadRegisterDefinitions, "aarch64-dead-defs",
65
                AARCH64_DEAD_REG_DEF_NAME, false, false)
66
67
34.0M
static bool usesFrameIndex(const MachineInstr &MI) {
68
34.0M
  for (const MachineOperand &MO : MI.uses())
69
82.9M
    
if (82.9M
MO.isFI()82.9M
)
70
534k
      return true;
71
33.4M
  return false;
72
33.4M
}
73
74
bool
75
AArch64DeadRegisterDefinitions::shouldSkip(const MachineInstr &MI,
76
33.3M
                                           const MachineFunction &MF) const {
77
33.3M
  if (!MF.getSubtarget<AArch64Subtarget>().hasLSE())
78
33.3M
    return false;
79
6.52k
80
6.52k
#define CASE_AARCH64_ATOMIC_(PREFIX) \
81
12.9k
  case AArch64::PREFIX##X: \
82
12.9k
  case AArch64::PREFIX##W: \
83
12.9k
  case AArch64::PREFIX##H: \
84
12.9k
  case AArch64::PREFIX##B
85
6.52k
86
6.52k
  
for (const MachineMemOperand *MMO : MI.memoperands()) 6.52k
{
87
1.13k
    if (
MMO->isAtomic()1.13k
) {
88
1.12k
      unsigned Opcode = MI.getOpcode();
89
1.12k
      switch (Opcode) {
90
408
      default:
91
408
        return false;
92
0
        break;
93
1.12k
94
720
      
CASE_AARCH64_ATOMIC_720
(LDADDA):
95
720
      
CASE_AARCH64_ATOMIC_720
(LDADDAL):
96
2.88k
97
720
      
CASE_AARCH64_ATOMIC_720
(LDCLRA):
98
720
      
CASE_AARCH64_ATOMIC_720
(LDCLRAL):
99
2.88k
100
720
      
CASE_AARCH64_ATOMIC_720
(LDEORA):
101
720
      
CASE_AARCH64_ATOMIC_720
(LDEORAL):
102
2.88k
103
720
      
CASE_AARCH64_ATOMIC_720
(LDSETA):
104
720
      
CASE_AARCH64_ATOMIC_720
(LDSETAL):
105
2.88k
106
720
      
CASE_AARCH64_ATOMIC_720
(LDSMAXA):
107
720
      
CASE_AARCH64_ATOMIC_720
(LDSMAXAL):
108
2.88k
109
720
      
CASE_AARCH64_ATOMIC_720
(LDSMINA):
110
720
      
CASE_AARCH64_ATOMIC_720
(LDSMINAL):
111
2.88k
112
720
      
CASE_AARCH64_ATOMIC_720
(LDUMAXA):
113
720
      
CASE_AARCH64_ATOMIC_720
(LDUMAXAL):
114
2.88k
115
720
      
CASE_AARCH64_ATOMIC_720
(LDUMINA):
116
720
      
CASE_AARCH64_ATOMIC_720
(LDUMINAL):
117
2.88k
118
720
      
CASE_AARCH64_ATOMIC_720
(SWPA):
119
720
      
CASE_AARCH64_ATOMIC_720
(SWPAL):
120
720
        return true;
121
0
        break;
122
5.39k
                                                                    }
123
5.39k
    }
124
1.13k
  }
125
5.39k
126
5.39k
#undef CASE_AARCH64_ATOMIC_
127
5.39k
128
5.39k
  return false;
129
5.39k
}
130
131
void AArch64DeadRegisterDefinitions::processMachineBasicBlock(
132
3.82M
    MachineBasicBlock &MBB) {
133
3.82M
  const MachineFunction &MF = *MBB.getParent();
134
34.0M
  for (MachineInstr &MI : MBB) {
135
34.0M
    if (
usesFrameIndex(MI)34.0M
) {
136
534k
      // We need to skip this instruction because while it appears to have a
137
534k
      // dead def it uses a frame index which might expand into a multi
138
534k
      // instruction sequence during EPI.
139
534k
      DEBUG(dbgs() << "    Ignoring, operand is frame index\n");
140
534k
      continue;
141
534k
    }
142
33.4M
    
if (33.4M
MI.definesRegister(AArch64::XZR) || 33.4M
MI.definesRegister(AArch64::WZR)33.4M
) {
143
155k
      // It is not allowed to write to the same register (not even the zero
144
155k
      // register) twice in a single instruction.
145
155k
      DEBUG(dbgs() << "    Ignoring, XZR or WZR already used by the instruction\n");
146
155k
      continue;
147
155k
    }
148
33.3M
149
33.3M
    
if (33.3M
shouldSkip(MI, MF)33.3M
) {
150
720
      DEBUG(dbgs() << "    Ignoring, Atomic instruction with acquire semantics using WZR/XZR\n");
151
720
      continue;
152
720
    }
153
33.3M
154
33.3M
    const MCInstrDesc &Desc = MI.getDesc();
155
53.4M
    for (int I = 0, E = Desc.getNumDefs(); 
I != E53.4M
;
++I20.1M
) {
156
21.0M
      MachineOperand &MO = MI.getOperand(I);
157
21.0M
      if (
!MO.isReg() || 21.0M
!MO.isDef()21.0M
)
158
39
        continue;
159
21.0M
      // We should not have any relevant physreg defs that are replacable by
160
21.0M
      // zero before register allocation. So we just check for dead vreg defs.
161
21.0M
      unsigned Reg = MO.getReg();
162
21.0M
      if (!TargetRegisterInfo::isVirtualRegister(Reg) ||
163
15.5M
          
(!MO.isDead() && 15.5M
!MRI->use_nodbg_empty(Reg)15.5M
))
164
20.1M
        continue;
165
21.0M
      assert(!MO.isImplicit() && "Unexpected implicit def!");
166
876k
      DEBUG(dbgs() << "  Dead def operand #" << I << " in:\n    ";
167
876k
            MI.print(dbgs()));
168
876k
      // Be careful not to change the register if it's a tied operand.
169
876k
      if (
MI.isRegTiedToUseOperand(I)876k
) {
170
0
        DEBUG(dbgs() << "    Ignoring, def is tied operand.\n");
171
0
        continue;
172
0
      }
173
876k
      const TargetRegisterClass *RC = TII->getRegClass(Desc, I, TRI, MF);
174
876k
      unsigned NewReg;
175
876k
      if (
RC == nullptr876k
) {
176
12
        DEBUG(dbgs() << "    Ignoring, register is not a GPR.\n");
177
12
        continue;
178
876k
      } else 
if (876k
RC->contains(AArch64::WZR)876k
)
179
541k
        NewReg = AArch64::WZR;
180
335k
      else 
if (335k
RC->contains(AArch64::XZR)335k
)
181
335k
        NewReg = AArch64::XZR;
182
1
      else {
183
1
        DEBUG(dbgs() << "    Ignoring, register is not a GPR.\n");
184
876k
        continue;
185
876k
      }
186
876k
      
DEBUG876k
(dbgs() << " Replacing with zero register. New:\n ");
187
876k
      MO.setReg(NewReg);
188
876k
      MO.setIsDead();
189
876k
      DEBUG(MI.print(dbgs()));
190
21.0M
      ++NumDeadDefsReplaced;
191
21.0M
      Changed = true;
192
21.0M
      // Only replace one dead register, see check for zero register above.
193
21.0M
      break;
194
21.0M
    }
195
34.0M
  }
196
3.82M
}
197
198
// Scan the function for instructions that have a dead definition of a
199
// register. Replace that register with the zero register when possible.
200
456k
bool AArch64DeadRegisterDefinitions::runOnMachineFunction(MachineFunction &MF) {
201
456k
  if (skipFunction(*MF.getFunction()))
202
1
    return false;
203
456k
204
456k
  TRI = MF.getSubtarget().getRegisterInfo();
205
456k
  TII = MF.getSubtarget().getInstrInfo();
206
456k
  MRI = &MF.getRegInfo();
207
456k
  DEBUG(dbgs() << "***** AArch64DeadRegisterDefinitions *****\n");
208
456k
  Changed = false;
209
456k
  for (auto &MBB : MF)
210
3.82M
    processMachineBasicBlock(MBB);
211
456k
  return Changed;
212
456k
}
213
214
13.8k
FunctionPass *llvm::createAArch64DeadRegisterDefinitions() {
215
13.8k
  return new AArch64DeadRegisterDefinitions();
216
13.8k
}