Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/ARM/ARMTargetMachine.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- ARMTargetMachine.cpp - Define TargetMachine for ARM ---------------===//
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
//
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "ARM.h"
14
#include "ARMSubtarget.h"
15
#include "ARMMacroFusion.h"
16
#include "ARMTargetMachine.h"
17
#include "ARMTargetObjectFile.h"
18
#include "ARMTargetTransformInfo.h"
19
#include "MCTargetDesc/ARMMCTargetDesc.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/ExecutionDepsFix.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 initializeARMExecutionDepsFixPass(PassRegistry&);
79
}
80
81
123k
extern "C" void LLVMInitializeARMTarget() {
82
123k
  // Register the target.
83
123k
  RegisterTargetMachine<ARMLETargetMachine> X(getTheARMLETarget());
84
123k
  RegisterTargetMachine<ARMLETargetMachine> A(getTheThumbLETarget());
85
123k
  RegisterTargetMachine<ARMBETargetMachine> Y(getTheARMBETarget());
86
123k
  RegisterTargetMachine<ARMBETargetMachine> B(getTheThumbBETarget());
87
123k
88
123k
  PassRegistry &Registry = *PassRegistry::getPassRegistry();
89
123k
  initializeGlobalISel(Registry);
90
123k
  initializeARMLoadStoreOptPass(Registry);
91
123k
  initializeARMPreAllocLoadStoreOptPass(Registry);
92
123k
  initializeARMConstantIslandsPass(Registry);
93
123k
  initializeARMExecutionDepsFixPass(Registry);
94
123k
  initializeARMExpandPseudoPass(Registry);
95
123k
}
96
97
4.88k
static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
98
4.88k
  if (TT.isOSBinFormatMachO())
99
2.72k
    return llvm::make_unique<TargetLoweringObjectFileMachO>();
100
2.15k
  
if (2.15k
TT.isOSWindows()2.15k
)
101
112
    return llvm::make_unique<TargetLoweringObjectFileCOFF>();
102
2.04k
  return llvm::make_unique<ARMElfTargetObjectFile>();
103
2.04k
}
104
105
static ARMBaseTargetMachine::ARMABI
106
computeTargetABI(const Triple &TT, StringRef CPU,
107
9.76k
                 const TargetOptions &Options) {
108
9.76k
  StringRef ABIName = Options.MCOptions.getABIName();
109
9.76k
110
9.76k
  if (ABIName.empty())
111
5.94k
    ABIName = ARM::computeDefaultTargetABI(TT, CPU);
112
9.76k
113
9.76k
  if (ABIName == "aapcs16")
114
840
    return ARMBaseTargetMachine::ARM_ABI_AAPCS16;
115
8.92k
  else 
if (8.92k
ABIName.startswith("aapcs")8.92k
)
116
6.29k
    return ARMBaseTargetMachine::ARM_ABI_AAPCS;
117
2.63k
  else 
if (2.63k
ABIName.startswith("apcs")2.63k
)
118
2.63k
    return ARMBaseTargetMachine::ARM_ABI_APCS;
119
0
120
0
  
llvm_unreachable0
("Unhandled/unknown ABI Name!");
121
0
  return ARMBaseTargetMachine::ARM_ABI_UNKNOWN;
122
9.76k
}
123
124
static std::string computeDataLayout(const Triple &TT, StringRef CPU,
125
                                     const TargetOptions &Options,
126
4.88k
                                     bool isLittle) {
127
4.88k
  auto ABI = computeTargetABI(TT, CPU, Options);
128
4.88k
  std::string Ret;
129
4.88k
130
4.88k
  if (isLittle)
131
4.88k
    // Little endian.
132
4.84k
    Ret += "e";
133
4.88k
  else
134
4.88k
    // Big endian.
135
41
    Ret += "E";
136
4.88k
137
4.88k
  Ret += DataLayout::getManglingComponent(TT);
138
4.88k
139
4.88k
  // Pointers are 32 bits and aligned to 32 bits.
140
4.88k
  Ret += "-p:32:32";
141
4.88k
142
4.88k
  // ABIs other than APCS have 64 bit integers with natural alignment.
143
4.88k
  if (ABI != ARMBaseTargetMachine::ARM_ABI_APCS)
144
3.56k
    Ret += "-i64:64";
145
4.88k
146
4.88k
  // We have 64 bits floats. The APCS ABI requires them to be aligned to 32
147
4.88k
  // bits, others to 64 bits. We always try to align to 64 bits.
148
4.88k
  if (ABI == ARMBaseTargetMachine::ARM_ABI_APCS)
149
1.31k
    Ret += "-f64:32:64";
150
4.88k
151
4.88k
  // We have 128 and 64 bit vectors. The APCS ABI aligns them to 32 bits, others
152
4.88k
  // to 64. We always ty to give them natural alignment.
153
4.88k
  if (ABI == ARMBaseTargetMachine::ARM_ABI_APCS)
154
1.31k
    Ret += "-v64:32:64-v128:32:128";
155
3.56k
  else 
if (3.56k
ABI != ARMBaseTargetMachine::ARM_ABI_AAPCS163.56k
)
156
3.14k
    Ret += "-v128:64:128";
157
4.88k
158
4.88k
  // Try to align aggregates to 32 bits (the default is 64 bits, which has no
159
4.88k
  // particular hardware support on 32-bit ARM).
160
4.88k
  Ret += "-a:0:32";
161
4.88k
162
4.88k
  // Integer registers are 32 bits.
163
4.88k
  Ret += "-n32";
164
4.88k
165
4.88k
  // The stack is 128 bit aligned on NaCl, 64 bit aligned on AAPCS and 32 bit
166
4.88k
  // aligned everywhere else.
167
4.88k
  if (
TT.isOSNaCl() || 4.88k
ABI == ARMBaseTargetMachine::ARM_ABI_AAPCS164.87k
)
168
426
    Ret += "-S128";
169
4.45k
  else 
if (4.45k
ABI == ARMBaseTargetMachine::ARM_ABI_AAPCS4.45k
)
170
3.13k
    Ret += "-S64";
171
4.45k
  else
172
1.31k
    Ret += "-S32";
173
4.88k
174
4.88k
  return Ret;
175
4.88k
}
176
177
static Reloc::Model getEffectiveRelocModel(const Triple &TT,
178
4.88k
                                           Optional<Reloc::Model> RM) {
179
4.88k
  if (!RM.hasValue())
180
4.88k
    // Default relocation model on Darwin is PIC.
181
2.40k
    
return TT.isOSBinFormatMachO() ? 2.40k
Reloc::PIC_642
:
Reloc::Static1.76k
;
182
2.47k
183
2.47k
  
if (2.47k
*RM == Reloc::ROPI || 2.47k
*RM == Reloc::RWPI2.45k
||
*RM == Reloc::ROPI_RWPI2.44k
)
184
2.47k
    assert(TT.isOSBinFormatELF() &&
185
2.47k
           "ROPI/RWPI currently only supported for ELF");
186
2.47k
187
2.47k
  // DynamicNoPIC is only used on darwin.
188
2.47k
  if (
*RM == Reloc::DynamicNoPIC && 2.47k
!TT.isOSDarwin()104
)
189
37
    return Reloc::Static;
190
2.44k
191
2.44k
  return *RM;
192
2.44k
}
193
194
4.88k
static CodeModel::Model getEffectiveCodeModel(Optional<CodeModel::Model> CM) {
195
4.88k
  if (CM)
196
4
    return *CM;
197
4.88k
  return CodeModel::Small;
198
4.88k
}
199
200
/// Create an ARM architecture model.
201
///
202
ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, const Triple &TT,
203
                                           StringRef CPU, StringRef FS,
204
                                           const TargetOptions &Options,
205
                                           Optional<Reloc::Model> RM,
206
                                           Optional<CodeModel::Model> CM,
207
                                           CodeGenOpt::Level OL, bool isLittle)
208
    : LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options, isLittle), TT,
209
                        CPU, FS, Options, getEffectiveRelocModel(TT, RM),
210
                        getEffectiveCodeModel(CM), OL),
211
      TargetABI(computeTargetABI(TT, CPU, Options)),
212
4.88k
      TLOF(createTLOF(getTargetTriple())), isLittle(isLittle) {
213
4.88k
214
4.88k
  // Default to triple-appropriate float ABI
215
4.88k
  if (
Options.FloatABIType == FloatABI::Default4.88k
) {
216
2.93k
    if (TargetTriple.getEnvironment() == Triple::GNUEABIHF ||
217
2.81k
        TargetTriple.getEnvironment() == Triple::MuslEABIHF ||
218
2.80k
        TargetTriple.getEnvironment() == Triple::EABIHF ||
219
2.77k
        TargetTriple.isOSWindows() ||
220
2.66k
        TargetABI == ARMBaseTargetMachine::ARM_ABI_AAPCS16)
221
300
      this->Options.FloatABIType = FloatABI::Hard;
222
2.93k
    else
223
2.63k
      this->Options.FloatABIType = FloatABI::Soft;
224
2.93k
  }
225
4.88k
226
4.88k
  // Default to triple-appropriate EABI
227
4.88k
  if (Options.EABIVersion == EABI::Default ||
228
4.88k
      
Options.EABIVersion == EABI::Unknown2.16k
) {
229
4.84k
    // musl is compatible with glibc with regard to EABI version
230
4.84k
    if ((TargetTriple.getEnvironment() == Triple::GNUEABI ||
231
4.28k
         TargetTriple.getEnvironment() == Triple::GNUEABIHF ||
232
4.14k
         TargetTriple.getEnvironment() == Triple::MuslEABI ||
233
4.12k
         TargetTriple.getEnvironment() == Triple::MuslEABIHF) &&
234
719
        
!(TargetTriple.isOSWindows() || 719
TargetTriple.isOSDarwin()719
))
235
719
      this->Options.EABIVersion = EABI::GNU;
236
4.84k
    else
237
4.12k
      this->Options.EABIVersion = EABI::EABI5;
238
4.84k
  }
239
4.88k
240
4.88k
  initAsmInfo();
241
4.88k
}
242
243
3.01k
ARMBaseTargetMachine::~ARMBaseTargetMachine() = default;
244
245
const ARMSubtarget *
246
477k
ARMBaseTargetMachine::getSubtargetImpl(const Function &F) const {
247
477k
  Attribute CPUAttr = F.getFnAttribute("target-cpu");
248
477k
  Attribute FSAttr = F.getFnAttribute("target-features");
249
477k
250
477k
  std::string CPU = !CPUAttr.hasAttribute(Attribute::None)
251
336k
                        ? CPUAttr.getValueAsString().str()
252
140k
                        : TargetCPU;
253
477k
  std::string FS = !FSAttr.hasAttribute(Attribute::None)
254
372k
                       ? FSAttr.getValueAsString().str()
255
104k
                       : TargetFS;
256
477k
257
477k
  // FIXME: This is related to the code below to reset the target options,
258
477k
  // we need to know whether or not the soft float flag is set on the
259
477k
  // function before we can generate a subtarget. We also need to use
260
477k
  // it as a key for the subtarget since that can be the only difference
261
477k
  // between two functions.
262
477k
  bool SoftFloat =
263
477k
      F.getFnAttribute("use-soft-float").getValueAsString() == "true";
264
477k
  // If the soft float attribute is set on the function turn on the soft float
265
477k
  // subtarget feature.
266
477k
  if (SoftFloat)
267
34.6k
    
FS += FS.empty() ? 34.6k
"+soft-float"16
:
",+soft-float"34.6k
;
268
477k
269
477k
  auto &I = SubtargetMap[CPU + FS];
270
477k
  if (
!I477k
) {
271
4.34k
    // This needs to be done before we create a new subtarget since any
272
4.34k
    // creation will depend on the TM and the code generation flags on the
273
4.34k
    // function that reside in TargetOptions.
274
4.34k
    resetTargetOptions(F);
275
4.34k
    I = llvm::make_unique<ARMSubtarget>(TargetTriple, CPU, FS, *this, isLittle);
276
4.34k
277
4.34k
    if (
!I->isThumb() && 4.34k
!I->hasARMOps()1.58k
)
278
3
      F.getContext().emitError("Function '" + F.getName() + "' uses ARM "
279
3
          "instructions, but the target does not support ARM mode execution.");
280
4.34k
  }
281
477k
282
477k
  return I.get();
283
477k
}
284
285
10.9k
TargetIRAnalysis ARMBaseTargetMachine::getTargetIRAnalysis() {
286
269k
  return TargetIRAnalysis([this](const Function &F) {
287
269k
    return TargetTransformInfo(ARMTTIImpl(this, F));
288
269k
  });
289
10.9k
}
290
291
ARMLETargetMachine::ARMLETargetMachine(const Target &T, const Triple &TT,
292
                                       StringRef CPU, StringRef FS,
293
                                       const TargetOptions &Options,
294
                                       Optional<Reloc::Model> RM,
295
                                       Optional<CodeModel::Model> CM,
296
                                       CodeGenOpt::Level OL, bool JIT)
297
4.84k
    : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
298
299
ARMBETargetMachine::ARMBETargetMachine(const Target &T, const Triple &TT,
300
                                       StringRef CPU, StringRef FS,
301
                                       const TargetOptions &Options,
302
                                       Optional<Reloc::Model> RM,
303
                                       Optional<CodeModel::Model> CM,
304
                                       CodeGenOpt::Level OL, bool JIT)
305
41
    : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
306
307
namespace {
308
309
/// ARM Code Generator Pass Configuration Options.
310
class ARMPassConfig : public TargetPassConfig {
311
public:
312
  ARMPassConfig(ARMBaseTargetMachine &TM, PassManagerBase &PM)
313
4.55k
    : TargetPassConfig(TM, PM) {}
314
315
4.36k
  ARMBaseTargetMachine &getARMTargetMachine() const {
316
4.36k
    return getTM<ARMBaseTargetMachine>();
317
4.36k
  }
318
319
  ScheduleDAGInstrs *
320
1.55k
  createMachineScheduler(MachineSchedContext *C) const override {
321
1.55k
    ScheduleDAGMILive *DAG = createGenericSchedLive(C);
322
1.55k
    // add DAG Mutations here.
323
1.55k
    const ARMSubtarget &ST = C->MF->getSubtarget<ARMSubtarget>();
324
1.55k
    if (ST.hasFusion())
325
3
      DAG->addMutation(createARMMacroFusionDAGMutation());
326
1.55k
    return DAG;
327
1.55k
  }
328
329
  ScheduleDAGInstrs *
330
2
  createPostMachineScheduler(MachineSchedContext *C) const override {
331
2
    ScheduleDAGMI *DAG = createGenericSchedPostRA(C);
332
2
    // add DAG Mutations here.
333
2
    const ARMSubtarget &ST = C->MF->getSubtarget<ARMSubtarget>();
334
2
    if (ST.hasFusion())
335
0
      DAG->addMutation(createARMMacroFusionDAGMutation());
336
2
    return DAG;
337
2
  }
338
339
  void addIRPasses() override;
340
  bool addPreISel() override;
341
  bool addInstSelector() override;
342
  bool addIRTranslator() override;
343
  bool addLegalizeMachineIR() override;
344
  bool addRegBankSelect() override;
345
  bool addGlobalInstructionSelect() override;
346
  void addPreRegAlloc() override;
347
  void addPreSched2() override;
348
  void addPreEmitPass() override;
349
};
350
351
class ARMExecutionDepsFix : public ExecutionDepsFix {
352
public:
353
  static char ID;
354
4.12k
  ARMExecutionDepsFix() : ExecutionDepsFix(ID, ARM::DPRRegClass) {}
355
4.12k
  StringRef getPassName() const override {
356
4.12k
    return "ARM Execution Dependency Fix";
357
4.12k
  }
358
};
359
char ARMExecutionDepsFix::ID;
360
361
} // end anonymous namespace
362
363
INITIALIZE_PASS(ARMExecutionDepsFix, "arm-execution-deps-fix",
364
                "ARM Execution Dependency Fix", false, false)
365
366
4.55k
TargetPassConfig *ARMBaseTargetMachine::createPassConfig(PassManagerBase &PM) {
367
4.55k
  return new ARMPassConfig(*this, PM);
368
4.55k
}
369
370
4.38k
void ARMPassConfig::addIRPasses() {
371
4.38k
  if (TM->Options.ThreadModel == ThreadModel::Single)
372
1
    addPass(createLowerAtomicPass());
373
4.38k
  else
374
4.38k
    addPass(createAtomicExpandPass());
375
4.38k
376
4.38k
  // Cmpxchg instructions are often used with a subsequent comparison to
377
4.38k
  // determine whether it succeeded. We can exploit existing control-flow in
378
4.38k
  // ldrex/strex loops to simplify this, but it needs tidying up.
379
4.38k
  if (
TM->getOptLevel() != CodeGenOpt::None && 4.38k
EnableAtomicTidy4.12k
)
380
4.07k
    
addPass(createCFGSimplificationPass(-1, [this](const Function &F) 4.07k
{
381
15.8k
      const auto &ST = this->TM->getSubtarget<ARMSubtarget>(F);
382
11.8k
      return ST.hasAnyDataBarrier() && !ST.isThumb1Only();
383
4.07k
    }));
384
4.38k
385
4.38k
  TargetPassConfig::addIRPasses();
386
4.38k
387
4.38k
  // Match interleaved memory accesses to ldN/stN intrinsics.
388
4.38k
  if (TM->getOptLevel() != CodeGenOpt::None)
389
4.12k
    addPass(createInterleavedAccessPass());
390
4.38k
}
391
392
4.38k
bool ARMPassConfig::addPreISel() {
393
4.38k
  if ((TM->getOptLevel() != CodeGenOpt::None &&
394
4.12k
       EnableGlobalMerge == cl::BOU_UNSET) ||
395
4.38k
      
EnableGlobalMerge == cl::BOU_TRUE274
) {
396
4.12k
    // FIXME: This is using the thumb1 only constant value for
397
4.12k
    // maximal global offset for merging globals. We may want
398
4.12k
    // to look into using the old value for non-thumb1 code of
399
4.12k
    // 4095 based on the TargetMachine, but this starts to become
400
4.12k
    // tricky when doing code gen per function.
401
4.12k
    bool OnlyOptimizeForSize = (TM->getOptLevel() < CodeGenOpt::Aggressive) &&
402
3.21k
                               (EnableGlobalMerge == cl::BOU_UNSET);
403
4.12k
    // Merging of extern globals is enabled by default on non-Mach-O as we
404
4.12k
    // expect it to be generally either beneficial or harmless. On Mach-O it
405
4.12k
    // is disabled as we emit the .subsections_via_symbols directive which
406
4.12k
    // means that merging extern globals is not safe.
407
4.12k
    bool MergeExternalByDefault = !TM->getTargetTriple().isOSBinFormatMachO();
408
4.12k
    addPass(createGlobalMergePass(TM, 127, OnlyOptimizeForSize,
409
4.12k
                                  MergeExternalByDefault));
410
4.12k
  }
411
4.38k
412
4.38k
  return false;
413
4.38k
}
414
415
4.36k
bool ARMPassConfig::addInstSelector() {
416
4.36k
  addPass(createARMISelDag(getARMTargetMachine(), getOptLevel()));
417
4.36k
  return false;
418
4.36k
}
419
420
29
bool ARMPassConfig::addIRTranslator() {
421
29
  addPass(new IRTranslator());
422
29
  return false;
423
29
}
424
425
29
bool ARMPassConfig::addLegalizeMachineIR() {
426
29
  addPass(new Legalizer());
427
29
  return false;
428
29
}
429
430
29
bool ARMPassConfig::addRegBankSelect() {
431
29
  addPass(new RegBankSelect());
432
29
  return false;
433
29
}
434
435
29
bool ARMPassConfig::addGlobalInstructionSelect() {
436
29
  addPass(new InstructionSelect());
437
29
  return false;
438
29
}
439
440
4.38k
void ARMPassConfig::addPreRegAlloc() {
441
4.38k
  if (
getOptLevel() != CodeGenOpt::None4.38k
) {
442
4.12k
    addPass(createMLxExpansionPass());
443
4.12k
444
4.12k
    if (EnableARMLoadStoreOpt)
445
4.12k
      addPass(createARMLoadStoreOptimizationPass(/* pre-register alloc */ true));
446
4.12k
447
4.12k
    if (!DisableA15SDOptimization)
448
4.12k
      addPass(createA15SDOptimizerPass());
449
4.12k
  }
450
4.38k
}
451
452
4.38k
void ARMPassConfig::addPreSched2() {
453
4.38k
  if (
getOptLevel() != CodeGenOpt::None4.38k
) {
454
4.12k
    if (EnableARMLoadStoreOpt)
455
4.12k
      addPass(createARMLoadStoreOptimizationPass());
456
4.12k
457
4.12k
    addPass(new ARMExecutionDepsFix());
458
4.12k
  }
459
4.38k
460
4.38k
  // Expand some pseudo instructions into multiple instructions to allow
461
4.38k
  // proper scheduling.
462
4.38k
  addPass(createARMExpandPseudoPass());
463
4.38k
464
4.38k
  if (
getOptLevel() != CodeGenOpt::None4.38k
) {
465
4.12k
    // in v8, IfConversion depends on Thumb instruction widths
466
15.8k
    addPass(createThumb2SizeReductionPass([this](const Function &F) {
467
15.8k
      return this->TM->getSubtarget<ARMSubtarget>(F).restrictIT();
468
15.8k
    }));
469
4.12k
470
15.8k
    addPass(createIfConverter([](const MachineFunction &MF) {
471
15.8k
      return !MF.getSubtarget<ARMSubtarget>().isThumb1Only();
472
15.8k
    }));
473
4.12k
  }
474
4.38k
  addPass(createThumb2ITBlockPass());
475
4.38k
}
476
477
4.38k
void ARMPassConfig::addPreEmitPass() {
478
4.38k
  addPass(createThumb2SizeReductionPass());
479
4.38k
480
4.38k
  // Constant island pass work on unbundled instructions.
481
17.0k
  addPass(createUnpackMachineBundles([](const MachineFunction &MF) {
482
17.0k
    return MF.getSubtarget<ARMSubtarget>().isThumb2();
483
17.0k
  }));
484
4.38k
485
4.38k
  // Don't optimize barriers at -O0.
486
4.38k
  if (getOptLevel() != CodeGenOpt::None)
487
4.12k
    addPass(createARMOptimizeBarriersPass());
488
4.38k
489
4.38k
  addPass(createARMConstantIslandPass());
490
4.38k
}