Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/ARM/ARMTargetMachine.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- ARMTargetMachine.cpp - Define TargetMachine for ARM ---------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
//
10
//===----------------------------------------------------------------------===//
11
12
#include "ARMTargetMachine.h"
13
#include "ARM.h"
14
#include "ARMMacroFusion.h"
15
#include "ARMSubtarget.h"
16
#include "ARMTargetObjectFile.h"
17
#include "ARMTargetTransformInfo.h"
18
#include "MCTargetDesc/ARMMCTargetDesc.h"
19
#include "TargetInfo/ARMTargetInfo.h"
20
#include "llvm/ADT/Optional.h"
21
#include "llvm/ADT/STLExtras.h"
22
#include "llvm/ADT/StringRef.h"
23
#include "llvm/ADT/Triple.h"
24
#include "llvm/Analysis/TargetTransformInfo.h"
25
#include "llvm/CodeGen/ExecutionDomainFix.h"
26
#include "llvm/CodeGen/GlobalISel/CallLowering.h"
27
#include "llvm/CodeGen/GlobalISel/IRTranslator.h"
28
#include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
29
#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
30
#include "llvm/CodeGen/GlobalISel/Legalizer.h"
31
#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
32
#include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
33
#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
34
#include "llvm/CodeGen/MachineFunction.h"
35
#include "llvm/CodeGen/MachineScheduler.h"
36
#include "llvm/CodeGen/Passes.h"
37
#include "llvm/CodeGen/TargetPassConfig.h"
38
#include "llvm/IR/Attributes.h"
39
#include "llvm/IR/DataLayout.h"
40
#include "llvm/IR/Function.h"
41
#include "llvm/Pass.h"
42
#include "llvm/Support/CodeGen.h"
43
#include "llvm/Support/CommandLine.h"
44
#include "llvm/Support/ErrorHandling.h"
45
#include "llvm/Support/TargetParser.h"
46
#include "llvm/Support/TargetRegistry.h"
47
#include "llvm/Target/TargetLoweringObjectFile.h"
48
#include "llvm/Target/TargetOptions.h"
49
#include "llvm/Transforms/Scalar.h"
50
#include <cassert>
51
#include <memory>
52
#include <string>
53
54
using namespace llvm;
55
56
static cl::opt<bool>
57
DisableA15SDOptimization("disable-a15-sd-optimization", cl::Hidden,
58
                   cl::desc("Inhibit optimization of S->D register accesses on A15"),
59
                   cl::init(false));
60
61
static cl::opt<bool>
62
EnableAtomicTidy("arm-atomic-cfg-tidy", cl::Hidden,
63
                 cl::desc("Run SimplifyCFG after expanding atomic operations"
64
                          " to make use of cmpxchg flow-based information"),
65
                 cl::init(true));
66
67
static cl::opt<bool>
68
EnableARMLoadStoreOpt("arm-load-store-opt", cl::Hidden,
69
                      cl::desc("Enable ARM load/store optimization pass"),
70
                      cl::init(true));
71
72
// FIXME: Unify control over GlobalMerge.
73
static cl::opt<cl::boolOrDefault>
74
EnableGlobalMerge("arm-global-merge", cl::Hidden,
75
                  cl::desc("Enable the global merge pass"));
76
77
namespace llvm {
78
  void initializeARMExecutionDomainFixPass(PassRegistry&);
79
}
80
81
139k
extern "C" void LLVMInitializeARMTarget() {
82
139k
  // Register the target.
83
139k
  RegisterTargetMachine<ARMLETargetMachine> X(getTheARMLETarget());
84
139k
  RegisterTargetMachine<ARMLETargetMachine> A(getTheThumbLETarget());
85
139k
  RegisterTargetMachine<ARMBETargetMachine> Y(getTheARMBETarget());
86
139k
  RegisterTargetMachine<ARMBETargetMachine> B(getTheThumbBETarget());
87
139k
88
139k
  PassRegistry &Registry = *PassRegistry::getPassRegistry();
89
139k
  initializeGlobalISel(Registry);
90
139k
  initializeARMLoadStoreOptPass(Registry);
91
139k
  initializeARMPreAllocLoadStoreOptPass(Registry);
92
139k
  initializeARMParallelDSPPass(Registry);
93
139k
  initializeARMCodeGenPreparePass(Registry);
94
139k
  initializeARMConstantIslandsPass(Registry);
95
139k
  initializeARMExecutionDomainFixPass(Registry);
96
139k
  initializeARMExpandPseudoPass(Registry);
97
139k
  initializeThumb2SizeReducePass(Registry);
98
139k
  initializeMVEVPTBlockPass(Registry);
99
139k
  initializeARMLowOverheadLoopsPass(Registry);
100
139k
}
101
102
5.99k
static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
103
5.99k
  if (TT.isOSBinFormatMachO())
104
3.10k
    return llvm::make_unique<TargetLoweringObjectFileMachO>();
105
2.89k
  if (TT.isOSWindows())
106
133
    return llvm::make_unique<TargetLoweringObjectFileCOFF>();
107
2.76k
  return llvm::make_unique<ARMElfTargetObjectFile>();
108
2.76k
}
109
110
static ARMBaseTargetMachine::ARMABI
111
computeTargetABI(const Triple &TT, StringRef CPU,
112
11.9k
                 const TargetOptions &Options) {
113
11.9k
  StringRef ABIName = Options.MCOptions.getABIName();
114
11.9k
115
11.9k
  if (ABIName.empty())
116
7.46k
    ABIName = ARM::computeDefaultTargetABI(TT, CPU);
117
11.9k
118
11.9k
  if (ABIName == "aapcs16")
119
1.06k
    return ARMBaseTargetMachine::ARM_ABI_AAPCS16;
120
10.9k
  else if (ABIName.startswith("aapcs"))
121
7.77k
    return ARMBaseTargetMachine::ARM_ABI_AAPCS;
122
3.14k
  else if (ABIName.startswith("apcs"))
123
3.14k
    return ARMBaseTargetMachine::ARM_ABI_APCS;
124
0
125
0
  llvm_unreachable("Unhandled/unknown ABI Name!");
126
0
  return ARMBaseTargetMachine::ARM_ABI_UNKNOWN;
127
0
}
128
129
static std::string computeDataLayout(const Triple &TT, StringRef CPU,
130
                                     const TargetOptions &Options,
131
5.99k
                                     bool isLittle) {
132
5.99k
  auto ABI = computeTargetABI(TT, CPU, Options);
133
5.99k
  std::string Ret;
134
5.99k
135
5.99k
  if (isLittle)
136
5.94k
    // Little endian.
137
5.94k
    Ret += "e";
138
57
  else
139
57
    // Big endian.
140
57
    Ret += "E";
141
5.99k
142
5.99k
  Ret += DataLayout::getManglingComponent(TT);
143
5.99k
144
5.99k
  // Pointers are 32 bits and aligned to 32 bits.
145
5.99k
  Ret += "-p:32:32";
146
5.99k
147
5.99k
  // Function pointers are aligned to 8 bits (because the LSB stores the
148
5.99k
  // ARM/Thumb state).
149
5.99k
  Ret += "-Fi8";
150
5.99k
151
5.99k
  // ABIs other than APCS have 64 bit integers with natural alignment.
152
5.99k
  if (ABI != ARMBaseTargetMachine::ARM_ABI_APCS)
153
4.42k
    Ret += "-i64:64";
154
5.99k
155
5.99k
  // We have 64 bits floats. The APCS ABI requires them to be aligned to 32
156
5.99k
  // bits, others to 64 bits. We always try to align to 64 bits.
157
5.99k
  if (ABI == ARMBaseTargetMachine::ARM_ABI_APCS)
158
1.57k
    Ret += "-f64:32:64";
159
5.99k
160
5.99k
  // We have 128 and 64 bit vectors. The APCS ABI aligns them to 32 bits, others
161
5.99k
  // to 64. We always ty to give them natural alignment.
162
5.99k
  if (ABI == ARMBaseTargetMachine::ARM_ABI_APCS)
163
1.57k
    Ret += "-v64:32:64-v128:32:128";
164
4.42k
  else if (ABI != ARMBaseTargetMachine::ARM_ABI_AAPCS16)
165
3.88k
    Ret += "-v128:64:128";
166
5.99k
167
5.99k
  // Try to align aggregates to 32 bits (the default is 64 bits, which has no
168
5.99k
  // particular hardware support on 32-bit ARM).
169
5.99k
  Ret += "-a:0:32";
170
5.99k
171
5.99k
  // Integer registers are 32 bits.
172
5.99k
  Ret += "-n32";
173
5.99k
174
5.99k
  // The stack is 128 bit aligned on NaCl, 64 bit aligned on AAPCS and 32 bit
175
5.99k
  // aligned everywhere else.
176
5.99k
  if (TT.isOSNaCl() || 
ABI == ARMBaseTargetMachine::ARM_ABI_AAPCS165.99k
)
177
540
    Ret += "-S128";
178
5.45k
  else if (ABI == ARMBaseTargetMachine::ARM_ABI_AAPCS)
179
3.88k
    Ret += "-S64";
180
1.57k
  else
181
1.57k
    Ret += "-S32";
182
5.99k
183
5.99k
  return Ret;
184
5.99k
}
185
186
static Reloc::Model getEffectiveRelocModel(const Triple &TT,
187
5.99k
                                           Optional<Reloc::Model> RM) {
188
5.99k
  if (!RM.hasValue())
189
3.08k
    // Default relocation model on Darwin is PIC.
190
3.08k
    return TT.isOSBinFormatMachO() ? 
Reloc::PIC_666
:
Reloc::Static2.41k
;
191
2.91k
192
2.91k
  if (*RM == Reloc::ROPI || 
*RM == Reloc::RWPI2.88k
||
*RM == Reloc::ROPI_RWPI2.86k
)
193
2.91k
    assert(TT.isOSBinFormatELF() &&
194
2.91k
           "ROPI/RWPI currently only supported for ELF");
195
2.91k
196
2.91k
  // DynamicNoPIC is only used on darwin.
197
2.91k
  if (*RM == Reloc::DynamicNoPIC && 
!TT.isOSDarwin()104
)
198
37
    return Reloc::Static;
199
2.87k
200
2.87k
  return *RM;
201
2.87k
}
202
203
/// Create an ARM architecture model.
204
///
205
ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, const Triple &TT,
206
                                           StringRef CPU, StringRef FS,
207
                                           const TargetOptions &Options,
208
                                           Optional<Reloc::Model> RM,
209
                                           Optional<CodeModel::Model> CM,
210
                                           CodeGenOpt::Level OL, bool isLittle)
211
    : LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options, isLittle), TT,
212
                        CPU, FS, Options, getEffectiveRelocModel(TT, RM),
213
                        getEffectiveCodeModel(CM, CodeModel::Small), OL),
214
      TargetABI(computeTargetABI(TT, CPU, Options)),
215
5.99k
      TLOF(createTLOF(getTargetTriple())), isLittle(isLittle) {
216
5.99k
217
5.99k
  // Default to triple-appropriate float ABI
218
5.99k
  if (Options.FloatABIType == FloatABI::Default) {
219
3.65k
    if (isTargetHardFloat())
220
368
      this->Options.FloatABIType = FloatABI::Hard;
221
3.29k
    else
222
3.29k
      this->Options.FloatABIType = FloatABI::Soft;
223
3.65k
  }
224
5.99k
225
5.99k
  // Default to triple-appropriate EABI
226
5.99k
  if (Options.EABIVersion == EABI::Default ||
227
5.99k
      
Options.EABIVersion == EABI::Unknown2.56k
) {
228
5.95k
    // musl is compatible with glibc with regard to EABI version
229
5.95k
    if ((TargetTriple.getEnvironment() == Triple::GNUEABI ||
230
5.95k
         
TargetTriple.getEnvironment() == Triple::GNUEABIHF5.31k
||
231
5.95k
         
TargetTriple.getEnvironment() == Triple::MuslEABI5.16k
||
232
5.95k
         
TargetTriple.getEnvironment() == Triple::MuslEABIHF5.13k
) &&
233
5.95k
        
!(821
TargetTriple.isOSWindows()821
||
TargetTriple.isOSDarwin()821
))
234
821
      this->Options.EABIVersion = EABI::GNU;
235
5.13k
    else
236
5.13k
      this->Options.EABIVersion = EABI::EABI5;
237
5.95k
  }
238
5.99k
239
5.99k
  if (TT.isOSBinFormatMachO()) {
240
3.10k
    this->Options.TrapUnreachable = true;
241
3.10k
    this->Options.NoTrapAfterNoreturn = true;
242
3.10k
  }
243
5.99k
244
5.99k
  initAsmInfo();
245
5.99k
}
246
247
3.78k
ARMBaseTargetMachine::~ARMBaseTargetMachine() = default;
248
249
const ARMSubtarget *
250
1.06M
ARMBaseTargetMachine::getSubtargetImpl(const Function &F) const {
251
1.06M
  Attribute CPUAttr = F.getFnAttribute("target-cpu");
252
1.06M
  Attribute FSAttr = F.getFnAttribute("target-features");
253
1.06M
254
1.06M
  std::string CPU = !CPUAttr.hasAttribute(Attribute::None)
255
1.06M
                        ? 
CPUAttr.getValueAsString().str()799k
256
1.06M
                        : 
TargetCPU266k
;
257
1.06M
  std::string FS = !FSAttr.hasAttribute(Attribute::None)
258
1.06M
                       ? 
FSAttr.getValueAsString().str()888k
259
1.06M
                       : 
TargetFS177k
;
260
1.06M
261
1.06M
  // FIXME: This is related to the code below to reset the target options,
262
1.06M
  // we need to know whether or not the soft float flag is set on the
263
1.06M
  // function before we can generate a subtarget. We also need to use
264
1.06M
  // it as a key for the subtarget since that can be the only difference
265
1.06M
  // between two functions.
266
1.06M
  bool SoftFloat =
267
1.06M
      F.getFnAttribute("use-soft-float").getValueAsString() == "true";
268
1.06M
  // If the soft float attribute is set on the function turn on the soft float
269
1.06M
  // subtarget feature.
270
1.06M
  if (SoftFloat)
271
36.0k
    FS += FS.empty() ? 
"+soft-float"20
:
",+soft-float"35.9k
;
272
1.06M
273
1.06M
  // Use the optminsize to identify the subtarget, but don't use it in the
274
1.06M
  // feature string.
275
1.06M
  std::string Key = CPU + FS;
276
1.06M
  if (F.hasMinSize())
277
59.1k
    Key += "+minsize";
278
1.06M
279
1.06M
  auto &I = SubtargetMap[Key];
280
1.06M
  if (!I) {
281
5.27k
    // This needs to be done before we create a new subtarget since any
282
5.27k
    // creation will depend on the TM and the code generation flags on the
283
5.27k
    // function that reside in TargetOptions.
284
5.27k
    resetTargetOptions(F);
285
5.27k
    I = llvm::make_unique<ARMSubtarget>(TargetTriple, CPU, FS, *this, isLittle,
286
5.27k
                                        F.hasMinSize());
287
5.27k
288
5.27k
    if (!I->isThumb() && 
!I->hasARMOps()1.86k
)
289
3
      F.getContext().emitError("Function '" + F.getName() + "' uses ARM "
290
3
          "instructions, but the target does not support ARM mode execution.");
291
5.27k
  }
292
1.06M
293
1.06M
  return I.get();
294
1.06M
}
295
296
TargetTransformInfo
297
656k
ARMBaseTargetMachine::getTargetTransformInfo(const Function &F) {
298
656k
  return TargetTransformInfo(ARMTTIImpl(this, F));
299
656k
}
300
301
ARMLETargetMachine::ARMLETargetMachine(const Target &T, const Triple &TT,
302
                                       StringRef CPU, StringRef FS,
303
                                       const TargetOptions &Options,
304
                                       Optional<Reloc::Model> RM,
305
                                       Optional<CodeModel::Model> CM,
306
                                       CodeGenOpt::Level OL, bool JIT)
307
5.94k
    : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
308
309
ARMBETargetMachine::ARMBETargetMachine(const Target &T, const Triple &TT,
310
                                       StringRef CPU, StringRef FS,
311
                                       const TargetOptions &Options,
312
                                       Optional<Reloc::Model> RM,
313
                                       Optional<CodeModel::Model> CM,
314
                                       CodeGenOpt::Level OL, bool JIT)
315
57
    : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
316
317
namespace {
318
319
/// ARM Code Generator Pass Configuration Options.
320
class ARMPassConfig : public TargetPassConfig {
321
public:
322
  ARMPassConfig(ARMBaseTargetMachine &TM, PassManagerBase &PM)
323
5.60k
      : TargetPassConfig(TM, PM) {
324
5.60k
    if (TM.getOptLevel() != CodeGenOpt::None) {
325
5.03k
      ARMGenSubtargetInfo STI(TM.getTargetTriple(), TM.getTargetCPU(),
326
5.03k
                              TM.getTargetFeatureString());
327
5.03k
      if (STI.hasFeature(ARM::FeatureUseMISched))
328
951
        substitutePass(&PostRASchedulerID, &PostMachineSchedulerID);
329
5.03k
    }
330
5.60k
  }
331
332
5.14k
  ARMBaseTargetMachine &getARMTargetMachine() const {
333
5.14k
    return getTM<ARMBaseTargetMachine>();
334
5.14k
  }
335
336
  ScheduleDAGInstrs *
337
3.70k
  createMachineScheduler(MachineSchedContext *C) const override {
338
3.70k
    ScheduleDAGMILive *DAG = createGenericSchedLive(C);
339
3.70k
    // add DAG Mutations here.
340
3.70k
    const ARMSubtarget &ST = C->MF->getSubtarget<ARMSubtarget>();
341
3.70k
    if (ST.hasFusion())
342
5
      DAG->addMutation(createARMMacroFusionDAGMutation());
343
3.70k
    return DAG;
344
3.70k
  }
345
346
  ScheduleDAGInstrs *
347
1.13k
  createPostMachineScheduler(MachineSchedContext *C) const override {
348
1.13k
    ScheduleDAGMI *DAG = createGenericSchedPostRA(C);
349
1.13k
    // add DAG Mutations here.
350
1.13k
    const ARMSubtarget &ST = C->MF->getSubtarget<ARMSubtarget>();
351
1.13k
    if (ST.hasFusion())
352
2
      DAG->addMutation(createARMMacroFusionDAGMutation());
353
1.13k
    return DAG;
354
1.13k
  }
355
356
  void addIRPasses() override;
357
  void addCodeGenPrepare() override;
358
  bool addPreISel() override;
359
  bool addInstSelector() override;
360
  bool addIRTranslator() override;
361
  bool addLegalizeMachineIR() override;
362
  bool addRegBankSelect() override;
363
  bool addGlobalInstructionSelect() override;
364
  void addPreRegAlloc() override;
365
  void addPreSched2() override;
366
  void addPreEmitPass() override;
367
368
  std::unique_ptr<CSEConfigBase> getCSEConfig() const override;
369
};
370
371
class ARMExecutionDomainFix : public ExecutionDomainFix {
372
public:
373
  static char ID;
374
4.91k
  ARMExecutionDomainFix() : ExecutionDomainFix(ID, ARM::DPRRegClass) {}
375
30.1k
  StringRef getPassName() const override {
376
30.1k
    return "ARM Execution Domain Fix";
377
30.1k
  }
378
};
379
char ARMExecutionDomainFix::ID;
380
381
} // end anonymous namespace
382
383
101k
INITIALIZE_PASS_BEGIN(ARMExecutionDomainFix, "arm-execution-domain-fix",
384
101k
  "ARM Execution Domain Fix", false, false)
385
101k
INITIALIZE_PASS_DEPENDENCY(ReachingDefAnalysis)
386
101k
INITIALIZE_PASS_END(ARMExecutionDomainFix, "arm-execution-domain-fix",
387
  "ARM Execution Domain Fix", false, false)
388
389
5.60k
TargetPassConfig *ARMBaseTargetMachine::createPassConfig(PassManagerBase &PM) {
390
5.60k
  return new ARMPassConfig(*this, PM);
391
5.60k
}
392
393
1.22k
std::unique_ptr<CSEConfigBase> ARMPassConfig::getCSEConfig() const {
394
1.22k
  return getStandardCSEConfigForOpt(TM->getOptLevel());
395
1.22k
}
396
397
5.19k
void ARMPassConfig::addIRPasses() {
398
5.19k
  if (TM->Options.ThreadModel == ThreadModel::Single)
399
1
    addPass(createLowerAtomicPass());
400
5.19k
  else
401
5.19k
    addPass(createAtomicExpandPass());
402
5.19k
403
5.19k
  // Cmpxchg instructions are often used with a subsequent comparison to
404
5.19k
  // determine whether it succeeded. We can exploit existing control-flow in
405
5.19k
  // ldrex/strex loops to simplify this, but it needs tidying up.
406
5.19k
  if (TM->getOptLevel() != CodeGenOpt::None && 
EnableAtomicTidy4.91k
)
407
4.86k
    addPass(createCFGSimplificationPass(
408
25.2k
        1, false, false, true, true, [this](const Function &F) {
409
25.2k
          const auto &ST = this->TM->getSubtarget<ARMSubtarget>(F);
410
25.2k
          return ST.hasAnyDataBarrier() && 
!ST.isThumb1Only()20.4k
;
411
25.2k
        }));
412
5.19k
413
5.19k
  TargetPassConfig::addIRPasses();
414
5.19k
415
5.19k
  // Run the parallel DSP pass.
416
5.19k
  if (getOptLevel() == CodeGenOpt::Aggressive) 
417
1.26k
    addPass(createARMParallelDSPPass());
418
5.19k
419
5.19k
  // Match interleaved memory accesses to ldN/stN intrinsics.
420
5.19k
  if (TM->getOptLevel() != CodeGenOpt::None)
421
4.91k
    addPass(createInterleavedAccessPass());
422
5.19k
}
423
424
5.19k
void ARMPassConfig::addCodeGenPrepare() {
425
5.19k
  if (getOptLevel() != CodeGenOpt::None)
426
4.91k
    addPass(createARMCodeGenPreparePass());
427
5.19k
  TargetPassConfig::addCodeGenPrepare();
428
5.19k
}
429
430
5.19k
bool ARMPassConfig::addPreISel() {
431
5.19k
  if ((TM->getOptLevel() != CodeGenOpt::None &&
432
5.19k
       
EnableGlobalMerge == cl::BOU_UNSET4.91k
) ||
433
5.19k
      
EnableGlobalMerge == cl::BOU_TRUE299
) {
434
4.91k
    // FIXME: This is using the thumb1 only constant value for
435
4.91k
    // maximal global offset for merging globals. We may want
436
4.91k
    // to look into using the old value for non-thumb1 code of
437
4.91k
    // 4095 based on the TargetMachine, but this starts to become
438
4.91k
    // tricky when doing code gen per function.
439
4.91k
    bool OnlyOptimizeForSize = (TM->getOptLevel() < CodeGenOpt::Aggressive) &&
440
4.91k
                               
(EnableGlobalMerge == cl::BOU_UNSET)3.65k
;
441
4.91k
    // Merging of extern globals is enabled by default on non-Mach-O as we
442
4.91k
    // expect it to be generally either beneficial or harmless. On Mach-O it
443
4.91k
    // is disabled as we emit the .subsections_via_symbols directive which
444
4.91k
    // means that merging extern globals is not safe.
445
4.91k
    bool MergeExternalByDefault = !TM->getTargetTriple().isOSBinFormatMachO();
446
4.91k
    addPass(createGlobalMergePass(TM, 127, OnlyOptimizeForSize,
447
4.91k
                                  MergeExternalByDefault));
448
4.91k
  }
449
5.19k
450
5.19k
  if (TM->getOptLevel() != CodeGenOpt::None)
451
4.91k
    addPass(createHardwareLoopsPass());
452
5.19k
453
5.19k
  return false;
454
5.19k
}
455
456
5.14k
bool ARMPassConfig::addInstSelector() {
457
5.14k
  addPass(createARMISelDag(getARMTargetMachine(), getOptLevel()));
458
5.14k
  return false;
459
5.14k
}
460
461
53
bool ARMPassConfig::addIRTranslator() {
462
53
  addPass(new IRTranslator());
463
53
  return false;
464
53
}
465
466
53
bool ARMPassConfig::addLegalizeMachineIR() {
467
53
  addPass(new Legalizer());
468
53
  return false;
469
53
}
470
471
53
bool ARMPassConfig::addRegBankSelect() {
472
53
  addPass(new RegBankSelect());
473
53
  return false;
474
53
}
475
476
53
bool ARMPassConfig::addGlobalInstructionSelect() {
477
53
  addPass(new InstructionSelect());
478
53
  return false;
479
53
}
480
481
5.19k
void ARMPassConfig::addPreRegAlloc() {
482
5.19k
  if (getOptLevel() != CodeGenOpt::None) {
483
4.91k
    addPass(createMLxExpansionPass());
484
4.91k
485
4.91k
    if (EnableARMLoadStoreOpt)
486
4.91k
      addPass(createARMLoadStoreOptimizationPass(/* pre-register alloc */ true));
487
4.91k
488
4.91k
    if (!DisableA15SDOptimization)
489
4.91k
      addPass(createA15SDOptimizerPass());
490
4.91k
  }
491
5.19k
}
492
493
5.19k
void ARMPassConfig::addPreSched2() {
494
5.19k
  if (getOptLevel() != CodeGenOpt::None) {
495
4.91k
    if (EnableARMLoadStoreOpt)
496
4.91k
      addPass(createARMLoadStoreOptimizationPass());
497
4.91k
498
4.91k
    addPass(new ARMExecutionDomainFix());
499
4.91k
    addPass(createBreakFalseDeps());
500
4.91k
  }
501
5.19k
502
5.19k
  // Expand some pseudo instructions into multiple instructions to allow
503
5.19k
  // proper scheduling.
504
5.19k
  addPass(createARMExpandPseudoPass());
505
5.19k
506
5.19k
  if (getOptLevel() != CodeGenOpt::None) {
507
4.91k
    // in v8, IfConversion depends on Thumb instruction widths
508
25.2k
    addPass(createThumb2SizeReductionPass([this](const Function &F) {
509
25.2k
      return this->TM->getSubtarget<ARMSubtarget>(F).restrictIT();
510
25.2k
    }));
511
4.91k
512
25.2k
    addPass(createIfConverter([](const MachineFunction &MF) {
513
25.2k
      return !MF.getSubtarget<ARMSubtarget>().isThumb1Only();
514
25.2k
    }));
515
4.91k
  }
516
5.19k
  addPass(createMVEVPTBlockPass());
517
5.19k
  addPass(createThumb2ITBlockPass());
518
5.19k
}
519
520
5.19k
void ARMPassConfig::addPreEmitPass() {
521
5.19k
  addPass(createThumb2SizeReductionPass());
522
5.19k
523
5.19k
  // Constant island pass work on unbundled instructions.
524
26.5k
  addPass(createUnpackMachineBundles([](const MachineFunction &MF) {
525
26.5k
    return MF.getSubtarget<ARMSubtarget>().isThumb2();
526
26.5k
  }));
527
5.19k
528
5.19k
  // Don't optimize barriers at -O0.
529
5.19k
  if (getOptLevel() != CodeGenOpt::None)
530
4.91k
    addPass(createARMOptimizeBarriersPass());
531
5.19k
532
5.19k
  addPass(createARMConstantIslandPass());
533
5.19k
  addPass(createARMLowOverheadLoopsPass());
534
5.19k
}