/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- SystemZTargetMachine.cpp - Define TargetMachine for SystemZ -------===// |
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 | | #include "SystemZTargetMachine.h" |
11 | | #include "MCTargetDesc/SystemZMCTargetDesc.h" |
12 | | #include "SystemZ.h" |
13 | | #include "SystemZMachineScheduler.h" |
14 | | #include "SystemZTargetTransformInfo.h" |
15 | | #include "llvm/ADT/Optional.h" |
16 | | #include "llvm/ADT/STLExtras.h" |
17 | | #include "llvm/ADT/SmallVector.h" |
18 | | #include "llvm/ADT/StringRef.h" |
19 | | #include "llvm/Analysis/TargetTransformInfo.h" |
20 | | #include "llvm/CodeGen/Passes.h" |
21 | | #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" |
22 | | #include "llvm/CodeGen/TargetPassConfig.h" |
23 | | #include "llvm/IR/DataLayout.h" |
24 | | #include "llvm/Support/CodeGen.h" |
25 | | #include "llvm/Support/TargetRegistry.h" |
26 | | #include "llvm/Target/TargetLoweringObjectFile.h" |
27 | | #include "llvm/Transforms/Scalar.h" |
28 | | #include <string> |
29 | | |
30 | | using namespace llvm; |
31 | | |
32 | 123k | extern "C" void LLVMInitializeSystemZTarget() { |
33 | 123k | // Register the target. |
34 | 123k | RegisterTargetMachine<SystemZTargetMachine> X(getTheSystemZTarget()); |
35 | 123k | } |
36 | | |
37 | | // Determine whether we use the vector ABI. |
38 | 857 | static bool UsesVectorABI(StringRef CPU, StringRef FS) { |
39 | 857 | // We use the vector ABI whenever the vector facility is avaiable. |
40 | 857 | // This is the case by default if CPU is z13 or later, and can be |
41 | 857 | // overridden via "[+-]vector" feature string elements. |
42 | 857 | bool VectorABI = true; |
43 | 857 | if (CPU.empty() || 857 CPU == "generic"435 || |
44 | 857 | CPU == "z10"434 || CPU == "z196"330 || CPU == "zEC12"278 ) |
45 | 593 | VectorABI = false; |
46 | 857 | |
47 | 857 | SmallVector<StringRef, 3> Features; |
48 | 857 | FS.split(Features, ',', -1, false /* KeepEmpty */); |
49 | 63 | for (auto &Feature : Features) { |
50 | 63 | if (Feature == "vector" || 63 Feature == "+vector"63 ) |
51 | 27 | VectorABI = true; |
52 | 63 | if (Feature == "-vector") |
53 | 6 | VectorABI = false; |
54 | 63 | } |
55 | 857 | |
56 | 857 | return VectorABI; |
57 | 857 | } |
58 | | |
59 | | static std::string computeDataLayout(const Triple &TT, StringRef CPU, |
60 | 857 | StringRef FS) { |
61 | 857 | bool VectorABI = UsesVectorABI(CPU, FS); |
62 | 857 | std::string Ret; |
63 | 857 | |
64 | 857 | // Big endian. |
65 | 857 | Ret += "E"; |
66 | 857 | |
67 | 857 | // Data mangling. |
68 | 857 | Ret += DataLayout::getManglingComponent(TT); |
69 | 857 | |
70 | 857 | // Make sure that global data has at least 16 bits of alignment by |
71 | 857 | // default, so that we can refer to it using LARL. We don't have any |
72 | 857 | // special requirements for stack variables though. |
73 | 857 | Ret += "-i1:8:16-i8:8:16"; |
74 | 857 | |
75 | 857 | // 64-bit integers are naturally aligned. |
76 | 857 | Ret += "-i64:64"; |
77 | 857 | |
78 | 857 | // 128-bit floats are aligned only to 64 bits. |
79 | 857 | Ret += "-f128:64"; |
80 | 857 | |
81 | 857 | // When using the vector ABI, 128-bit vectors are also aligned to 64 bits. |
82 | 857 | if (VectorABI) |
83 | 269 | Ret += "-v128:64"; |
84 | 857 | |
85 | 857 | // We prefer 16 bits of aligned for all globals; see above. |
86 | 857 | Ret += "-a:8:16"; |
87 | 857 | |
88 | 857 | // Integer registers are 32 or 64 bits. |
89 | 857 | Ret += "-n32:64"; |
90 | 857 | |
91 | 857 | return Ret; |
92 | 857 | } |
93 | | |
94 | 1.71k | static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) { |
95 | 1.71k | // Static code is suitable for use in a dynamic executable; there is no |
96 | 1.71k | // separate DynamicNoPIC model. |
97 | 1.71k | if (!RM.hasValue() || 1.71k *RM == Reloc::DynamicNoPIC100 ) |
98 | 1.61k | return Reloc::Static; |
99 | 100 | return *RM; |
100 | 100 | } |
101 | | |
102 | | // For SystemZ we define the models as follows: |
103 | | // |
104 | | // Small: BRASL can call any function and will use a stub if necessary. |
105 | | // Locally-binding symbols will always be in range of LARL. |
106 | | // |
107 | | // Medium: BRASL can call any function and will use a stub if necessary. |
108 | | // GOT slots and locally-defined text will always be in range |
109 | | // of LARL, but other symbols might not be. |
110 | | // |
111 | | // Large: Equivalent to Medium for now. |
112 | | // |
113 | | // Kernel: Equivalent to Medium for now. |
114 | | // |
115 | | // This means that any PIC module smaller than 4GB meets the |
116 | | // requirements of Small, so Small seems like the best default there. |
117 | | // |
118 | | // All symbols bind locally in a non-PIC module, so the choice is less |
119 | | // obvious. There are two cases: |
120 | | // |
121 | | // - When creating an executable, PLTs and copy relocations allow |
122 | | // us to treat external symbols as part of the executable. |
123 | | // Any executable smaller than 4GB meets the requirements of Small, |
124 | | // so that seems like the best default. |
125 | | // |
126 | | // - When creating JIT code, stubs will be in range of BRASL if the |
127 | | // image is less than 4GB in size. GOT entries will likewise be |
128 | | // in range of LARL. However, the JIT environment has no equivalent |
129 | | // of copy relocs, so locally-binding data symbols might not be in |
130 | | // the range of LARL. We need the Medium model in that case. |
131 | | static CodeModel::Model getEffectiveCodeModel(Optional<CodeModel::Model> CM, |
132 | 857 | Reloc::Model RM, bool JIT) { |
133 | 857 | if (CM) |
134 | 2 | return *CM; |
135 | 855 | if (855 JIT855 ) |
136 | 0 | return RM == Reloc::PIC_ ? 0 CodeModel::Small0 : CodeModel::Medium0 ; |
137 | 855 | return CodeModel::Small; |
138 | 855 | } |
139 | | |
140 | | SystemZTargetMachine::SystemZTargetMachine(const Target &T, const Triple &TT, |
141 | | StringRef CPU, StringRef FS, |
142 | | const TargetOptions &Options, |
143 | | Optional<Reloc::Model> RM, |
144 | | Optional<CodeModel::Model> CM, |
145 | | CodeGenOpt::Level OL, bool JIT) |
146 | | : LLVMTargetMachine( |
147 | | T, computeDataLayout(TT, CPU, FS), TT, CPU, FS, Options, |
148 | | getEffectiveRelocModel(RM), |
149 | | getEffectiveCodeModel(CM, getEffectiveRelocModel(RM), JIT), OL), |
150 | | TLOF(llvm::make_unique<TargetLoweringObjectFileELF>()), |
151 | 857 | Subtarget(TT, CPU, FS, *this) { |
152 | 857 | initAsmInfo(); |
153 | 857 | } |
154 | | |
155 | 847 | SystemZTargetMachine::~SystemZTargetMachine() = default; |
156 | | |
157 | | namespace { |
158 | | |
159 | | /// SystemZ Code Generator Pass Configuration Options. |
160 | | class SystemZPassConfig : public TargetPassConfig { |
161 | | public: |
162 | | SystemZPassConfig(SystemZTargetMachine &TM, PassManagerBase &PM) |
163 | 819 | : TargetPassConfig(TM, PM) {} |
164 | | |
165 | 4.75k | SystemZTargetMachine &getSystemZTargetMachine() const { |
166 | 4.75k | return getTM<SystemZTargetMachine>(); |
167 | 4.75k | } |
168 | | |
169 | | ScheduleDAGInstrs * |
170 | 2.85k | createPostMachineScheduler(MachineSchedContext *C) const override { |
171 | 2.85k | return new ScheduleDAGMI(C, |
172 | 2.85k | llvm::make_unique<SystemZPostRASchedStrategy>(C), |
173 | 2.85k | /*RemoveKillFlags=*/true); |
174 | 2.85k | } |
175 | | |
176 | | void addIRPasses() override; |
177 | | bool addInstSelector() override; |
178 | | bool addILPOpts() override; |
179 | | void addPreSched2() override; |
180 | | void addPreEmitPass() override; |
181 | | }; |
182 | | |
183 | | } // end anonymous namespace |
184 | | |
185 | 796 | void SystemZPassConfig::addIRPasses() { |
186 | 796 | if (getOptLevel() != CodeGenOpt::None796 ) { |
187 | 789 | addPass(createSystemZTDCPass()); |
188 | 789 | addPass(createLoopDataPrefetchPass()); |
189 | 789 | } |
190 | 796 | |
191 | 796 | TargetPassConfig::addIRPasses(); |
192 | 796 | } |
193 | | |
194 | 796 | bool SystemZPassConfig::addInstSelector() { |
195 | 796 | addPass(createSystemZISelDag(getSystemZTargetMachine(), getOptLevel())); |
196 | 796 | |
197 | 796 | if (getOptLevel() != CodeGenOpt::None) |
198 | 789 | addPass(createSystemZLDCleanupPass(getSystemZTargetMachine())); |
199 | 796 | |
200 | 796 | return false; |
201 | 796 | } |
202 | | |
203 | 789 | bool SystemZPassConfig::addILPOpts() { |
204 | 789 | addPass(&EarlyIfConverterID); |
205 | 789 | return true; |
206 | 789 | } |
207 | | |
208 | 796 | void SystemZPassConfig::addPreSched2() { |
209 | 796 | addPass(createSystemZExpandPseudoPass(getSystemZTargetMachine())); |
210 | 796 | |
211 | 796 | if (getOptLevel() != CodeGenOpt::None) |
212 | 789 | addPass(&IfConverterID); |
213 | 796 | } |
214 | | |
215 | 796 | void SystemZPassConfig::addPreEmitPass() { |
216 | 796 | // Do instruction shortening before compare elimination because some |
217 | 796 | // vector instructions will be shortened into opcodes that compare |
218 | 796 | // elimination recognizes. |
219 | 796 | if (getOptLevel() != CodeGenOpt::None) |
220 | 789 | addPass(createSystemZShortenInstPass(getSystemZTargetMachine()), false); |
221 | 796 | |
222 | 796 | // We eliminate comparisons here rather than earlier because some |
223 | 796 | // transformations can change the set of available CC values and we |
224 | 796 | // generally want those transformations to have priority. This is |
225 | 796 | // especially true in the commonest case where the result of the comparison |
226 | 796 | // is used by a single in-range branch instruction, since we will then |
227 | 796 | // be able to fuse the compare and the branch instead. |
228 | 796 | // |
229 | 796 | // For example, two-address NILF can sometimes be converted into |
230 | 796 | // three-address RISBLG. NILF produces a CC value that indicates whether |
231 | 796 | // the low word is zero, but RISBLG does not modify CC at all. On the |
232 | 796 | // other hand, 64-bit ANDs like NILL can sometimes be converted to RISBG. |
233 | 796 | // The CC value produced by NILL isn't useful for our purposes, but the |
234 | 796 | // value produced by RISBG can be used for any comparison with zero |
235 | 796 | // (not just equality). So there are some transformations that lose |
236 | 796 | // CC values (while still being worthwhile) and others that happen to make |
237 | 796 | // the CC result more useful than it was originally. |
238 | 796 | // |
239 | 796 | // Another reason is that we only want to use BRANCH ON COUNT in cases |
240 | 796 | // where we know that the count register is not going to be spilled. |
241 | 796 | // |
242 | 796 | // Doing it so late makes it more likely that a register will be reused |
243 | 796 | // between the comparison and the branch, but it isn't clear whether |
244 | 796 | // preventing that would be a win or not. |
245 | 796 | if (getOptLevel() != CodeGenOpt::None) |
246 | 789 | addPass(createSystemZElimComparePass(getSystemZTargetMachine()), false); |
247 | 796 | addPass(createSystemZLongBranchPass(getSystemZTargetMachine())); |
248 | 796 | |
249 | 796 | // Do final scheduling after all other optimizations, to get an |
250 | 796 | // optimal input for the decoder (branch relaxation must happen |
251 | 796 | // after block placement). |
252 | 796 | if (getOptLevel() != CodeGenOpt::None) |
253 | 789 | addPass(&PostMachineSchedulerID); |
254 | 796 | } |
255 | | |
256 | 819 | TargetPassConfig *SystemZTargetMachine::createPassConfig(PassManagerBase &PM) { |
257 | 819 | return new SystemZPassConfig(*this, PM); |
258 | 819 | } |
259 | | |
260 | 930 | TargetIRAnalysis SystemZTargetMachine::getTargetIRAnalysis() { |
261 | 58.1k | return TargetIRAnalysis([this](const Function &F) { |
262 | 58.1k | return TargetTransformInfo(SystemZTTIImpl(this, F)); |
263 | 58.1k | }); |
264 | 930 | } |