1251607Sdim//===-- SystemZTargetMachine.cpp - Define TargetMachine for SystemZ -------===//
2251607Sdim//
3251607Sdim//                     The LLVM Compiler Infrastructure
4251607Sdim//
5251607Sdim// This file is distributed under the University of Illinois Open Source
6251607Sdim// License. See LICENSE.TXT for details.
7251607Sdim//
8251607Sdim//===----------------------------------------------------------------------===//
9251607Sdim
10251607Sdim#include "SystemZTargetMachine.h"
11288943Sdim#include "SystemZTargetTransformInfo.h"
12251607Sdim#include "llvm/CodeGen/Passes.h"
13251607Sdim#include "llvm/Support/TargetRegistry.h"
14261991Sdim#include "llvm/Transforms/Scalar.h"
15280031Sdim#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
16251607Sdim
17251607Sdimusing namespace llvm;
18251607Sdim
19296417Sdimextern cl::opt<bool> MISchedPostRA;
20251607Sdimextern "C" void LLVMInitializeSystemZTarget() {
21251607Sdim  // Register the target.
22251607Sdim  RegisterTargetMachine<SystemZTargetMachine> X(TheSystemZTarget);
23251607Sdim}
24251607Sdim
25288943Sdim// Determine whether we use the vector ABI.
26288943Sdimstatic bool UsesVectorABI(StringRef CPU, StringRef FS) {
27288943Sdim  // We use the vector ABI whenever the vector facility is avaiable.
28288943Sdim  // This is the case by default if CPU is z13 or later, and can be
29288943Sdim  // overridden via "[+-]vector" feature string elements.
30288943Sdim  bool VectorABI = true;
31288943Sdim  if (CPU.empty() || CPU == "generic" ||
32288943Sdim      CPU == "z10" || CPU == "z196" || CPU == "zEC12")
33288943Sdim    VectorABI = false;
34288943Sdim
35288943Sdim  SmallVector<StringRef, 3> Features;
36296417Sdim  FS.split(Features, ',', -1, false /* KeepEmpty */);
37288943Sdim  for (auto &Feature : Features) {
38288943Sdim    if (Feature == "vector" || Feature == "+vector")
39288943Sdim      VectorABI = true;
40288943Sdim    if (Feature == "-vector")
41288943Sdim      VectorABI = false;
42288943Sdim  }
43288943Sdim
44288943Sdim  return VectorABI;
45288943Sdim}
46288943Sdim
47288943Sdimstatic std::string computeDataLayout(const Triple &TT, StringRef CPU,
48288943Sdim                                     StringRef FS) {
49288943Sdim  bool VectorABI = UsesVectorABI(CPU, FS);
50288943Sdim  std::string Ret = "";
51288943Sdim
52288943Sdim  // Big endian.
53288943Sdim  Ret += "E";
54288943Sdim
55288943Sdim  // Data mangling.
56288943Sdim  Ret += DataLayout::getManglingComponent(TT);
57288943Sdim
58288943Sdim  // Make sure that global data has at least 16 bits of alignment by
59288943Sdim  // default, so that we can refer to it using LARL.  We don't have any
60288943Sdim  // special requirements for stack variables though.
61288943Sdim  Ret += "-i1:8:16-i8:8:16";
62288943Sdim
63288943Sdim  // 64-bit integers are naturally aligned.
64288943Sdim  Ret += "-i64:64";
65288943Sdim
66288943Sdim  // 128-bit floats are aligned only to 64 bits.
67288943Sdim  Ret += "-f128:64";
68288943Sdim
69288943Sdim  // When using the vector ABI, 128-bit vectors are also aligned to 64 bits.
70288943Sdim  if (VectorABI)
71288943Sdim    Ret += "-v128:64";
72288943Sdim
73288943Sdim  // We prefer 16 bits of aligned for all globals; see above.
74288943Sdim  Ret += "-a:8:16";
75288943Sdim
76288943Sdim  // Integer registers are 32 or 64 bits.
77288943Sdim  Ret += "-n32:64";
78288943Sdim
79288943Sdim  return Ret;
80288943Sdim}
81288943Sdim
82288943SdimSystemZTargetMachine::SystemZTargetMachine(const Target &T, const Triple &TT,
83251607Sdim                                           StringRef CPU, StringRef FS,
84251607Sdim                                           const TargetOptions &Options,
85276479Sdim                                           Reloc::Model RM, CodeModel::Model CM,
86251607Sdim                                           CodeGenOpt::Level OL)
87288943Sdim    : LLVMTargetMachine(T, computeDataLayout(TT, CPU, FS), TT, CPU, FS, Options,
88288943Sdim                        RM, CM, OL),
89280031Sdim      TLOF(make_unique<TargetLoweringObjectFileELF>()),
90276479Sdim      Subtarget(TT, CPU, FS, *this) {
91261991Sdim  initAsmInfo();
92251607Sdim}
93251607Sdim
94280031SdimSystemZTargetMachine::~SystemZTargetMachine() {}
95280031Sdim
96251607Sdimnamespace {
97251607Sdim/// SystemZ Code Generator Pass Configuration Options.
98251607Sdimclass SystemZPassConfig : public TargetPassConfig {
99251607Sdimpublic:
100251607Sdim  SystemZPassConfig(SystemZTargetMachine *TM, PassManagerBase &PM)
101251607Sdim    : TargetPassConfig(TM, PM) {}
102251607Sdim
103251607Sdim  SystemZTargetMachine &getSystemZTargetMachine() const {
104251607Sdim    return getTM<SystemZTargetMachine>();
105251607Sdim  }
106251607Sdim
107276479Sdim  void addIRPasses() override;
108276479Sdim  bool addInstSelector() override;
109280031Sdim  void addPreSched2() override;
110280031Sdim  void addPreEmitPass() override;
111251607Sdim};
112251607Sdim} // end anonymous namespace
113251607Sdim
114261991Sdimvoid SystemZPassConfig::addIRPasses() {
115261991Sdim  TargetPassConfig::addIRPasses();
116261991Sdim}
117261991Sdim
118251607Sdimbool SystemZPassConfig::addInstSelector() {
119251607Sdim  addPass(createSystemZISelDag(getSystemZTargetMachine(), getOptLevel()));
120288943Sdim
121288943Sdim if (getOptLevel() != CodeGenOpt::None)
122288943Sdim    addPass(createSystemZLDCleanupPass(getSystemZTargetMachine()));
123288943Sdim
124251607Sdim  return false;
125251607Sdim}
126251607Sdim
127280031Sdimvoid SystemZPassConfig::addPreSched2() {
128276479Sdim  if (getOptLevel() != CodeGenOpt::None &&
129276479Sdim      getSystemZTargetMachine().getSubtargetImpl()->hasLoadStoreOnCond())
130261991Sdim    addPass(&IfConverterID);
131261991Sdim}
132261991Sdim
133280031Sdimvoid SystemZPassConfig::addPreEmitPass() {
134296417Sdim
135296417Sdim  // Do instruction shortening before compare elimination because some
136296417Sdim  // vector instructions will be shortened into opcodes that compare
137296417Sdim  // elimination recognizes.
138296417Sdim  if (getOptLevel() != CodeGenOpt::None)
139296417Sdim    addPass(createSystemZShortenInstPass(getSystemZTargetMachine()), false);
140296417Sdim
141261991Sdim  // We eliminate comparisons here rather than earlier because some
142261991Sdim  // transformations can change the set of available CC values and we
143261991Sdim  // generally want those transformations to have priority.  This is
144261991Sdim  // especially true in the commonest case where the result of the comparison
145261991Sdim  // is used by a single in-range branch instruction, since we will then
146261991Sdim  // be able to fuse the compare and the branch instead.
147261991Sdim  //
148261991Sdim  // For example, two-address NILF can sometimes be converted into
149261991Sdim  // three-address RISBLG.  NILF produces a CC value that indicates whether
150261991Sdim  // the low word is zero, but RISBLG does not modify CC at all.  On the
151261991Sdim  // other hand, 64-bit ANDs like NILL can sometimes be converted to RISBG.
152261991Sdim  // The CC value produced by NILL isn't useful for our purposes, but the
153261991Sdim  // value produced by RISBG can be used for any comparison with zero
154261991Sdim  // (not just equality).  So there are some transformations that lose
155261991Sdim  // CC values (while still being worthwhile) and others that happen to make
156261991Sdim  // the CC result more useful than it was originally.
157261991Sdim  //
158261991Sdim  // Another reason is that we only want to use BRANCH ON COUNT in cases
159261991Sdim  // where we know that the count register is not going to be spilled.
160261991Sdim  //
161261991Sdim  // Doing it so late makes it more likely that a register will be reused
162261991Sdim  // between the comparison and the branch, but it isn't clear whether
163261991Sdim  // preventing that would be a win or not.
164261991Sdim  if (getOptLevel() != CodeGenOpt::None)
165280031Sdim    addPass(createSystemZElimComparePass(getSystemZTargetMachine()), false);
166261991Sdim  addPass(createSystemZLongBranchPass(getSystemZTargetMachine()));
167296417Sdim
168296417Sdim  // Do final scheduling after all other optimizations, to get an
169296417Sdim  // optimal input for the decoder (branch relaxation must happen
170296417Sdim  // after block placement).
171296417Sdim  if (getOptLevel() != CodeGenOpt::None) {
172296417Sdim    if (MISchedPostRA)
173296417Sdim      addPass(&PostMachineSchedulerID);
174296417Sdim    else
175296417Sdim      addPass(&PostRASchedulerID);
176296417Sdim  }
177261991Sdim}
178261991Sdim
179251607SdimTargetPassConfig *SystemZTargetMachine::createPassConfig(PassManagerBase &PM) {
180251607Sdim  return new SystemZPassConfig(this, PM);
181251607Sdim}
182288943Sdim
183288943SdimTargetIRAnalysis SystemZTargetMachine::getTargetIRAnalysis() {
184296417Sdim  return TargetIRAnalysis([this](const Function &F) {
185288943Sdim    return TargetTransformInfo(SystemZTTIImpl(this, F));
186288943Sdim  });
187288943Sdim}
188