]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
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 "llvm/CodeGen/Passes.h" | |
12 | #include "llvm/Support/TargetRegistry.h" | |
13 | #include "llvm/Transforms/Scalar.h" | |
85aaf69f | 14 | #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" |
1a4d82fc JJ |
15 | |
16 | using namespace llvm; | |
17 | ||
18 | extern "C" void LLVMInitializeSystemZTarget() { | |
19 | // Register the target. | |
20 | RegisterTargetMachine<SystemZTargetMachine> X(TheSystemZTarget); | |
21 | } | |
22 | ||
23 | SystemZTargetMachine::SystemZTargetMachine(const Target &T, StringRef TT, | |
24 | StringRef CPU, StringRef FS, | |
25 | const TargetOptions &Options, | |
26 | Reloc::Model RM, CodeModel::Model CM, | |
27 | CodeGenOpt::Level OL) | |
28 | : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), | |
85aaf69f | 29 | TLOF(make_unique<TargetLoweringObjectFileELF>()), |
1a4d82fc JJ |
30 | Subtarget(TT, CPU, FS, *this) { |
31 | initAsmInfo(); | |
32 | } | |
33 | ||
85aaf69f SL |
34 | SystemZTargetMachine::~SystemZTargetMachine() {} |
35 | ||
1a4d82fc JJ |
36 | namespace { |
37 | /// SystemZ Code Generator Pass Configuration Options. | |
38 | class SystemZPassConfig : public TargetPassConfig { | |
39 | public: | |
40 | SystemZPassConfig(SystemZTargetMachine *TM, PassManagerBase &PM) | |
41 | : TargetPassConfig(TM, PM) {} | |
42 | ||
43 | SystemZTargetMachine &getSystemZTargetMachine() const { | |
44 | return getTM<SystemZTargetMachine>(); | |
45 | } | |
46 | ||
47 | void addIRPasses() override; | |
48 | bool addInstSelector() override; | |
85aaf69f SL |
49 | void addPreSched2() override; |
50 | void addPreEmitPass() override; | |
1a4d82fc JJ |
51 | }; |
52 | } // end anonymous namespace | |
53 | ||
54 | void SystemZPassConfig::addIRPasses() { | |
55 | TargetPassConfig::addIRPasses(); | |
56 | } | |
57 | ||
58 | bool SystemZPassConfig::addInstSelector() { | |
59 | addPass(createSystemZISelDag(getSystemZTargetMachine(), getOptLevel())); | |
60 | return false; | |
61 | } | |
62 | ||
85aaf69f | 63 | void SystemZPassConfig::addPreSched2() { |
1a4d82fc JJ |
64 | if (getOptLevel() != CodeGenOpt::None && |
65 | getSystemZTargetMachine().getSubtargetImpl()->hasLoadStoreOnCond()) | |
66 | addPass(&IfConverterID); | |
1a4d82fc JJ |
67 | } |
68 | ||
85aaf69f | 69 | void SystemZPassConfig::addPreEmitPass() { |
1a4d82fc JJ |
70 | // We eliminate comparisons here rather than earlier because some |
71 | // transformations can change the set of available CC values and we | |
72 | // generally want those transformations to have priority. This is | |
73 | // especially true in the commonest case where the result of the comparison | |
74 | // is used by a single in-range branch instruction, since we will then | |
75 | // be able to fuse the compare and the branch instead. | |
76 | // | |
77 | // For example, two-address NILF can sometimes be converted into | |
78 | // three-address RISBLG. NILF produces a CC value that indicates whether | |
79 | // the low word is zero, but RISBLG does not modify CC at all. On the | |
80 | // other hand, 64-bit ANDs like NILL can sometimes be converted to RISBG. | |
81 | // The CC value produced by NILL isn't useful for our purposes, but the | |
82 | // value produced by RISBG can be used for any comparison with zero | |
83 | // (not just equality). So there are some transformations that lose | |
84 | // CC values (while still being worthwhile) and others that happen to make | |
85 | // the CC result more useful than it was originally. | |
86 | // | |
87 | // Another reason is that we only want to use BRANCH ON COUNT in cases | |
88 | // where we know that the count register is not going to be spilled. | |
89 | // | |
90 | // Doing it so late makes it more likely that a register will be reused | |
91 | // between the comparison and the branch, but it isn't clear whether | |
92 | // preventing that would be a win or not. | |
93 | if (getOptLevel() != CodeGenOpt::None) | |
85aaf69f | 94 | addPass(createSystemZElimComparePass(getSystemZTargetMachine()), false); |
1a4d82fc | 95 | if (getOptLevel() != CodeGenOpt::None) |
85aaf69f | 96 | addPass(createSystemZShortenInstPass(getSystemZTargetMachine()), false); |
1a4d82fc | 97 | addPass(createSystemZLongBranchPass(getSystemZTargetMachine())); |
1a4d82fc JJ |
98 | } |
99 | ||
100 | TargetPassConfig *SystemZTargetMachine::createPassConfig(PassManagerBase &PM) { | |
101 | return new SystemZPassConfig(this, PM); | |
102 | } |