ARM64: diagnose use of v16-v31 in certain indexed NEON instructions.
[oota-llvm.git] / lib / Target / ARM64 / ARM64TargetMachine.cpp
1 //===-- ARM64TargetMachine.cpp - Define TargetMachine for ARM64 -----------===//
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 "ARM64.h"
14 #include "ARM64TargetMachine.h"
15 #include "llvm/PassManager.h"
16 #include "llvm/CodeGen/Passes.h"
17 #include "llvm/Support/CommandLine.h"
18 #include "llvm/Support/TargetRegistry.h"
19 #include "llvm/Target/TargetOptions.h"
20 #include "llvm/Transforms/Scalar.h"
21 using namespace llvm;
22
23 static cl::opt<bool> EnableCCMP("arm64-ccmp",
24                                 cl::desc("Enable the CCMP formation pass"),
25                                 cl::init(true));
26
27 static cl::opt<bool> EnableStPairSuppress("arm64-stp-suppress", cl::Hidden,
28                                           cl::desc("Suppress STP for ARM64"),
29                                           cl::init(true));
30
31 static cl::opt<bool>
32 EnablePromoteConstant("arm64-promote-const", cl::Hidden,
33                       cl::desc("Enable the promote constant pass"),
34                       cl::init(true));
35
36 static cl::opt<bool>
37 EnableCollectLOH("arm64-collect-loh", cl::Hidden,
38                  cl::desc("Enable the pass that emits the linker"
39                           " optimization hints (LOH)"),
40                  cl::init(true));
41
42 static cl::opt<bool>
43 EnableDeadRegisterElimination("arm64-dead-def-elimination", cl::Hidden,
44                               cl::desc("Enable the pass that removes dead"
45                                        " definitons and replaces stores to"
46                                        " them with stores to the zero"
47                                        " register"),
48                               cl::init(true));
49
50 extern "C" void LLVMInitializeARM64Target() {
51   // Register the target.
52   RegisterTargetMachine<ARM64leTargetMachine> X(TheARM64leTarget);
53   RegisterTargetMachine<ARM64beTargetMachine> Y(TheARM64beTarget);
54 }
55
56 /// TargetMachine ctor - Create an ARM64 architecture model.
57 ///
58 ARM64TargetMachine::ARM64TargetMachine(const Target &T, StringRef TT,
59                                        StringRef CPU, StringRef FS,
60                                        const TargetOptions &Options,
61                                        Reloc::Model RM, CodeModel::Model CM,
62                                        CodeGenOpt::Level OL,
63                                        bool LittleEndian)
64     : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
65       Subtarget(TT, CPU, FS, LittleEndian),
66       // This nested ternary is horrible, but DL needs to be properly initialized
67       // before TLInfo is constructed.
68       DL(Subtarget.isTargetMachO() ?
69          "e-m:o-i64:64-i128:128-n32:64-S128" :
70          (LittleEndian ?
71           "e-m:e-i64:64-i128:128-n32:64-S128" :
72           "E-m:e-i64:64-i128:128-n32:64-S128")),
73       InstrInfo(Subtarget), TLInfo(*this), FrameLowering(*this, Subtarget),
74       TSInfo(*this) {
75   initAsmInfo();
76 }
77
78 void ARM64leTargetMachine::anchor() { }
79
80 ARM64leTargetMachine::
81 ARM64leTargetMachine(const Target &T, StringRef TT,
82                        StringRef CPU, StringRef FS, const TargetOptions &Options,
83                        Reloc::Model RM, CodeModel::Model CM,
84                        CodeGenOpt::Level OL)
85   : ARM64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
86
87 void ARM64beTargetMachine::anchor() { }
88
89 ARM64beTargetMachine::
90 ARM64beTargetMachine(const Target &T, StringRef TT,
91                        StringRef CPU, StringRef FS, const TargetOptions &Options,
92                        Reloc::Model RM, CodeModel::Model CM,
93                        CodeGenOpt::Level OL)
94   : ARM64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
95
96 namespace {
97 /// ARM64 Code Generator Pass Configuration Options.
98 class ARM64PassConfig : public TargetPassConfig {
99 public:
100   ARM64PassConfig(ARM64TargetMachine *TM, PassManagerBase &PM)
101       : TargetPassConfig(TM, PM) {}
102
103   ARM64TargetMachine &getARM64TargetMachine() const {
104     return getTM<ARM64TargetMachine>();
105   }
106
107   virtual bool addPreISel();
108   virtual bool addInstSelector();
109   virtual bool addILPOpts();
110   virtual bool addPreRegAlloc();
111   virtual bool addPostRegAlloc();
112   virtual bool addPreSched2();
113   virtual bool addPreEmitPass();
114 };
115 } // namespace
116
117 void ARM64TargetMachine::addAnalysisPasses(PassManagerBase &PM) {
118   // Add first the target-independent BasicTTI pass, then our ARM64 pass. This
119   // allows the ARM64 pass to delegate to the target independent layer when
120   // appropriate.
121   PM.add(createBasicTargetTransformInfoPass(this));
122   PM.add(createARM64TargetTransformInfoPass(this));
123 }
124
125 TargetPassConfig *ARM64TargetMachine::createPassConfig(PassManagerBase &PM) {
126   return new ARM64PassConfig(this, PM);
127 }
128
129 // Pass Pipeline Configuration
130 bool ARM64PassConfig::addPreISel() {
131   // Run promote constant before global merge, so that the promoted constants
132   // get a chance to be merged
133   if (TM->getOptLevel() != CodeGenOpt::None && EnablePromoteConstant)
134     addPass(createARM64PromoteConstantPass());
135   if (TM->getOptLevel() != CodeGenOpt::None)
136     addPass(createGlobalMergePass(TM));
137   if (TM->getOptLevel() != CodeGenOpt::None)
138     addPass(createARM64AddressTypePromotionPass());
139
140   // Always expand atomic operations, we don't deal with atomicrmw or cmpxchg
141   // ourselves.
142   addPass(createAtomicExpandLoadLinkedPass(TM));
143
144   return false;
145 }
146
147 bool ARM64PassConfig::addInstSelector() {
148   addPass(createARM64ISelDag(getARM64TargetMachine(), getOptLevel()));
149
150   // For ELF, cleanup any local-dynamic TLS accesses (i.e. combine as many
151   // references to _TLS_MODULE_BASE_ as possible.
152   if (TM->getSubtarget<ARM64Subtarget>().isTargetELF() &&
153       getOptLevel() != CodeGenOpt::None)
154     addPass(createARM64CleanupLocalDynamicTLSPass());
155
156   return false;
157 }
158
159 bool ARM64PassConfig::addILPOpts() {
160   if (EnableCCMP)
161     addPass(createARM64ConditionalCompares());
162   addPass(&EarlyIfConverterID);
163   if (EnableStPairSuppress)
164     addPass(createARM64StorePairSuppressPass());
165   return true;
166 }
167
168 bool ARM64PassConfig::addPreRegAlloc() {
169   // Use AdvSIMD scalar instructions whenever profitable.
170   addPass(createARM64AdvSIMDScalar());
171   return true;
172 }
173
174 bool ARM64PassConfig::addPostRegAlloc() {
175   // Change dead register definitions to refer to the zero register.
176   if (EnableDeadRegisterElimination)
177     addPass(createARM64DeadRegisterDefinitions());
178   return true;
179 }
180
181 bool ARM64PassConfig::addPreSched2() {
182   // Expand some pseudo instructions to allow proper scheduling.
183   addPass(createARM64ExpandPseudoPass());
184   // Use load/store pair instructions when possible.
185   addPass(createARM64LoadStoreOptimizationPass());
186   return true;
187 }
188
189 bool ARM64PassConfig::addPreEmitPass() {
190   // Relax conditional branch instructions if they're otherwise out of
191   // range of their destination.
192   addPass(createARM64BranchRelaxation());
193   if (TM->getOptLevel() != CodeGenOpt::None && EnableCollectLOH &&
194       TM->getSubtarget<ARM64Subtarget>().isTargetMachO())
195     addPass(createARM64CollectLOHPass());
196   return true;
197 }