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"
11251607Sdim#include "llvm/CodeGen/Passes.h"
12251607Sdim#include "llvm/Support/TargetRegistry.h"
13263509Sdim#include "llvm/Transforms/Scalar.h"
14251607Sdim
15251607Sdimusing namespace llvm;
16251607Sdim
17251607Sdimextern "C" void LLVMInitializeSystemZTarget() {
18251607Sdim  // Register the target.
19251607Sdim  RegisterTargetMachine<SystemZTargetMachine> X(TheSystemZTarget);
20251607Sdim}
21251607Sdim
22251607SdimSystemZTargetMachine::SystemZTargetMachine(const Target &T, StringRef TT,
23251607Sdim                                           StringRef CPU, StringRef FS,
24251607Sdim                                           const TargetOptions &Options,
25251607Sdim                                           Reloc::Model RM,
26251607Sdim                                           CodeModel::Model CM,
27251607Sdim                                           CodeGenOpt::Level OL)
28251607Sdim  : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
29251607Sdim    Subtarget(TT, CPU, FS),
30251607Sdim    // Make sure that global data has at least 16 bits of alignment by default,
31251607Sdim    // so that we can refer to it using LARL.  We don't have any special
32251607Sdim    // requirements for stack variables though.
33251607Sdim    DL("E-p:64:64:64-i1:8:16-i8:8:16-i16:16-i32:32-i64:64"
34251607Sdim       "-f32:32-f64:64-f128:64-a0:8:16-n32:64"),
35251607Sdim    InstrInfo(*this), TLInfo(*this), TSInfo(*this),
36251607Sdim    FrameLowering(*this, Subtarget) {
37263509Sdim  initAsmInfo();
38251607Sdim}
39251607Sdim
40251607Sdimnamespace {
41251607Sdim/// SystemZ Code Generator Pass Configuration Options.
42251607Sdimclass SystemZPassConfig : public TargetPassConfig {
43251607Sdimpublic:
44251607Sdim  SystemZPassConfig(SystemZTargetMachine *TM, PassManagerBase &PM)
45251607Sdim    : TargetPassConfig(TM, PM) {}
46251607Sdim
47251607Sdim  SystemZTargetMachine &getSystemZTargetMachine() const {
48251607Sdim    return getTM<SystemZTargetMachine>();
49251607Sdim  }
50251607Sdim
51263509Sdim  virtual void addIRPasses() LLVM_OVERRIDE;
52263509Sdim  virtual bool addInstSelector() LLVM_OVERRIDE;
53263509Sdim  virtual bool addPreSched2() LLVM_OVERRIDE;
54263509Sdim  virtual bool addPreEmitPass() LLVM_OVERRIDE;
55251607Sdim};
56251607Sdim} // end anonymous namespace
57251607Sdim
58263509Sdimvoid SystemZPassConfig::addIRPasses() {
59263509Sdim  TargetPassConfig::addIRPasses();
60263509Sdim  addPass(createPartiallyInlineLibCallsPass());
61263509Sdim}
62263509Sdim
63251607Sdimbool SystemZPassConfig::addInstSelector() {
64251607Sdim  addPass(createSystemZISelDag(getSystemZTargetMachine(), getOptLevel()));
65251607Sdim  return false;
66251607Sdim}
67251607Sdim
68263509Sdimbool SystemZPassConfig::addPreSched2() {
69263509Sdim  if (getSystemZTargetMachine().getSubtargetImpl()->hasLoadStoreOnCond())
70263509Sdim    addPass(&IfConverterID);
71263509Sdim  return true;
72263509Sdim}
73263509Sdim
74263509Sdimbool SystemZPassConfig::addPreEmitPass() {
75263509Sdim  // We eliminate comparisons here rather than earlier because some
76263509Sdim  // transformations can change the set of available CC values and we
77263509Sdim  // generally want those transformations to have priority.  This is
78263509Sdim  // especially true in the commonest case where the result of the comparison
79263509Sdim  // is used by a single in-range branch instruction, since we will then
80263509Sdim  // be able to fuse the compare and the branch instead.
81263509Sdim  //
82263509Sdim  // For example, two-address NILF can sometimes be converted into
83263509Sdim  // three-address RISBLG.  NILF produces a CC value that indicates whether
84263509Sdim  // the low word is zero, but RISBLG does not modify CC at all.  On the
85263509Sdim  // other hand, 64-bit ANDs like NILL can sometimes be converted to RISBG.
86263509Sdim  // The CC value produced by NILL isn't useful for our purposes, but the
87263509Sdim  // value produced by RISBG can be used for any comparison with zero
88263509Sdim  // (not just equality).  So there are some transformations that lose
89263509Sdim  // CC values (while still being worthwhile) and others that happen to make
90263509Sdim  // the CC result more useful than it was originally.
91263509Sdim  //
92263509Sdim  // Another reason is that we only want to use BRANCH ON COUNT in cases
93263509Sdim  // where we know that the count register is not going to be spilled.
94263509Sdim  //
95263509Sdim  // Doing it so late makes it more likely that a register will be reused
96263509Sdim  // between the comparison and the branch, but it isn't clear whether
97263509Sdim  // preventing that would be a win or not.
98263509Sdim  if (getOptLevel() != CodeGenOpt::None)
99263509Sdim    addPass(createSystemZElimComparePass(getSystemZTargetMachine()));
100263509Sdim  if (getOptLevel() != CodeGenOpt::None)
101263509Sdim    addPass(createSystemZShortenInstPass(getSystemZTargetMachine()));
102263509Sdim  addPass(createSystemZLongBranchPass(getSystemZTargetMachine()));
103263509Sdim  return true;
104263509Sdim}
105263509Sdim
106251607SdimTargetPassConfig *SystemZTargetMachine::createPassConfig(PassManagerBase &PM) {
107251607Sdim  return new SystemZPassConfig(this, PM);
108251607Sdim}
109