]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/Target/SystemZ/SystemZTargetMachine.cpp
Vendor import of llvm trunk r305145:
[FreeBSD/FreeBSD.git] / lib / Target / SystemZ / SystemZTargetMachine.cpp
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 extern "C" void LLVMInitializeSystemZTarget() {
33   // Register the target.
34   RegisterTargetMachine<SystemZTargetMachine> X(getTheSystemZTarget());
35 }
36
37 // Determine whether we use the vector ABI.
38 static bool UsesVectorABI(StringRef CPU, StringRef FS) {
39   // We use the vector ABI whenever the vector facility is avaiable.
40   // This is the case by default if CPU is z13 or later, and can be
41   // overridden via "[+-]vector" feature string elements.
42   bool VectorABI = true;
43   if (CPU.empty() || CPU == "generic" ||
44       CPU == "z10" || CPU == "z196" || CPU == "zEC12")
45     VectorABI = false;
46
47   SmallVector<StringRef, 3> Features;
48   FS.split(Features, ',', -1, false /* KeepEmpty */);
49   for (auto &Feature : Features) {
50     if (Feature == "vector" || Feature == "+vector")
51       VectorABI = true;
52     if (Feature == "-vector")
53       VectorABI = false;
54   }
55
56   return VectorABI;
57 }
58
59 static std::string computeDataLayout(const Triple &TT, StringRef CPU,
60                                      StringRef FS) {
61   bool VectorABI = UsesVectorABI(CPU, FS);
62   std::string Ret;
63
64   // Big endian.
65   Ret += "E";
66
67   // Data mangling.
68   Ret += DataLayout::getManglingComponent(TT);
69
70   // Make sure that global data has at least 16 bits of alignment by
71   // default, so that we can refer to it using LARL.  We don't have any
72   // special requirements for stack variables though.
73   Ret += "-i1:8:16-i8:8:16";
74
75   // 64-bit integers are naturally aligned.
76   Ret += "-i64:64";
77
78   // 128-bit floats are aligned only to 64 bits.
79   Ret += "-f128:64";
80
81   // When using the vector ABI, 128-bit vectors are also aligned to 64 bits.
82   if (VectorABI)
83     Ret += "-v128:64";
84
85   // We prefer 16 bits of aligned for all globals; see above.
86   Ret += "-a:8:16";
87
88   // Integer registers are 32 or 64 bits.
89   Ret += "-n32:64";
90
91   return Ret;
92 }
93
94 static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) {
95   // Static code is suitable for use in a dynamic executable; there is no
96   // separate DynamicNoPIC model.
97   if (!RM.hasValue() || *RM == Reloc::DynamicNoPIC)
98     return Reloc::Static;
99   return *RM;
100 }
101
102 SystemZTargetMachine::SystemZTargetMachine(const Target &T, const Triple &TT,
103                                            StringRef CPU, StringRef FS,
104                                            const TargetOptions &Options,
105                                            Optional<Reloc::Model> RM,
106                                            CodeModel::Model CM,
107                                            CodeGenOpt::Level OL)
108     : LLVMTargetMachine(T, computeDataLayout(TT, CPU, FS), TT, CPU, FS, Options,
109                         getEffectiveRelocModel(RM), CM, OL),
110       TLOF(llvm::make_unique<TargetLoweringObjectFileELF>()),
111       Subtarget(TT, CPU, FS, *this) {
112   initAsmInfo();
113 }
114
115 SystemZTargetMachine::~SystemZTargetMachine() = default;
116
117 namespace {
118
119 /// SystemZ Code Generator Pass Configuration Options.
120 class SystemZPassConfig : public TargetPassConfig {
121 public:
122   SystemZPassConfig(SystemZTargetMachine &TM, PassManagerBase &PM)
123     : TargetPassConfig(TM, PM) {}
124
125   SystemZTargetMachine &getSystemZTargetMachine() const {
126     return getTM<SystemZTargetMachine>();
127   }
128
129   ScheduleDAGInstrs *
130   createPostMachineScheduler(MachineSchedContext *C) const override {
131     return new ScheduleDAGMI(C,
132                              llvm::make_unique<SystemZPostRASchedStrategy>(C),
133                              /*RemoveKillFlags=*/true);
134   }
135
136   void addIRPasses() override;
137   bool addInstSelector() override;
138   bool addILPOpts() override;
139   void addPreSched2() override;
140   void addPreEmitPass() override;
141 };
142
143 } // end anonymous namespace
144
145 void SystemZPassConfig::addIRPasses() {
146   if (getOptLevel() != CodeGenOpt::None)
147     addPass(createSystemZTDCPass());
148
149   TargetPassConfig::addIRPasses();
150 }
151
152 bool SystemZPassConfig::addInstSelector() {
153   addPass(createSystemZISelDag(getSystemZTargetMachine(), getOptLevel()));
154
155  if (getOptLevel() != CodeGenOpt::None)
156     addPass(createSystemZLDCleanupPass(getSystemZTargetMachine()));
157
158   return false;
159 }
160
161 bool SystemZPassConfig::addILPOpts() {
162   addPass(&EarlyIfConverterID);
163   return true;
164 }
165
166 void SystemZPassConfig::addPreSched2() {
167   addPass(createSystemZExpandPseudoPass(getSystemZTargetMachine()));
168
169   if (getOptLevel() != CodeGenOpt::None)
170     addPass(&IfConverterID);
171 }
172
173 void SystemZPassConfig::addPreEmitPass() {
174   // Do instruction shortening before compare elimination because some
175   // vector instructions will be shortened into opcodes that compare
176   // elimination recognizes.
177   if (getOptLevel() != CodeGenOpt::None)
178     addPass(createSystemZShortenInstPass(getSystemZTargetMachine()), false);
179
180   // We eliminate comparisons here rather than earlier because some
181   // transformations can change the set of available CC values and we
182   // generally want those transformations to have priority.  This is
183   // especially true in the commonest case where the result of the comparison
184   // is used by a single in-range branch instruction, since we will then
185   // be able to fuse the compare and the branch instead.
186   //
187   // For example, two-address NILF can sometimes be converted into
188   // three-address RISBLG.  NILF produces a CC value that indicates whether
189   // the low word is zero, but RISBLG does not modify CC at all.  On the
190   // other hand, 64-bit ANDs like NILL can sometimes be converted to RISBG.
191   // The CC value produced by NILL isn't useful for our purposes, but the
192   // value produced by RISBG can be used for any comparison with zero
193   // (not just equality).  So there are some transformations that lose
194   // CC values (while still being worthwhile) and others that happen to make
195   // the CC result more useful than it was originally.
196   //
197   // Another reason is that we only want to use BRANCH ON COUNT in cases
198   // where we know that the count register is not going to be spilled.
199   //
200   // Doing it so late makes it more likely that a register will be reused
201   // between the comparison and the branch, but it isn't clear whether
202   // preventing that would be a win or not.
203   if (getOptLevel() != CodeGenOpt::None)
204     addPass(createSystemZElimComparePass(getSystemZTargetMachine()), false);
205   addPass(createSystemZLongBranchPass(getSystemZTargetMachine()));
206
207   // Do final scheduling after all other optimizations, to get an
208   // optimal input for the decoder (branch relaxation must happen
209   // after block placement).
210   if (getOptLevel() != CodeGenOpt::None)
211     addPass(&PostMachineSchedulerID);
212 }
213
214 TargetPassConfig *SystemZTargetMachine::createPassConfig(PassManagerBase &PM) {
215   return new SystemZPassConfig(*this, PM);
216 }
217
218 TargetIRAnalysis SystemZTargetMachine::getTargetIRAnalysis() {
219   return TargetIRAnalysis([this](const Function &F) {
220     return TargetTransformInfo(SystemZTTIImpl(this, F));
221   });
222 }