X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FSystemZ%2FSystemZTargetMachine.cpp;h=d7c432e364b46ef42477a0e6d5c11be1b1ef83d8;hb=d12434058d49c78b3782b66f57482ed0c67dc44a;hp=01be4edf7d70f36cd20cf72a042ba25521059145;hpb=7df8462038c4393771a0961c60a2686169e4fd9a;p=oota-llvm.git diff --git a/lib/Target/SystemZ/SystemZTargetMachine.cpp b/lib/Target/SystemZ/SystemZTargetMachine.cpp index 01be4edf7d7..d7c432e364b 100644 --- a/lib/Target/SystemZ/SystemZTargetMachine.cpp +++ b/lib/Target/SystemZ/SystemZTargetMachine.cpp @@ -1,4 +1,4 @@ -//===-- SystemZTargetMachine.cpp - Define TargetMachine for SystemZ -----------===// +//===-- SystemZTargetMachine.cpp - Define TargetMachine for SystemZ -------===// // // The LLVM Compiler Infrastructure // @@ -6,66 +6,99 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// -//===----------------------------------------------------------------------===// -#include "SystemZTargetAsmInfo.h" #include "SystemZTargetMachine.h" -#include "SystemZ.h" -#include "llvm/Module.h" -#include "llvm/PassManager.h" -#include "llvm/Target/TargetMachineRegistry.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Transforms/Scalar.h" +#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" + using namespace llvm; -extern Target TheSystemZTarget; -namespace { +extern "C" void LLVMInitializeSystemZTarget() { // Register the target. - RegisterTarget X(TheSystemZTarget, - "systemz", - "SystemZ [experimental]"); + RegisterTargetMachine X(TheSystemZTarget); } -// Force static initialization. -extern "C" void LLVMInitializeSystemZTarget() { - +SystemZTargetMachine::SystemZTargetMachine(const Target &T, StringRef TT, + StringRef CPU, StringRef FS, + const TargetOptions &Options, + Reloc::Model RM, CodeModel::Model CM, + CodeGenOpt::Level OL) + : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), + TLOF(make_unique()), + Subtarget(TT, CPU, FS, *this) { + initAsmInfo(); } -const TargetAsmInfo *SystemZTargetMachine::createTargetAsmInfo() const { - // FIXME: Handle Solaris subtarget someday :) - return new SystemZTargetAsmInfo(*this); -} +SystemZTargetMachine::~SystemZTargetMachine() {} + +namespace { +/// SystemZ Code Generator Pass Configuration Options. +class SystemZPassConfig : public TargetPassConfig { +public: + SystemZPassConfig(SystemZTargetMachine *TM, PassManagerBase &PM) + : TargetPassConfig(TM, PM) {} -/// SystemZTargetMachine ctor - Create an ILP64 architecture model -/// -SystemZTargetMachine::SystemZTargetMachine(const Target &T, - const Module &M, - const std::string &FS) - : LLVMTargetMachine(T), - Subtarget(*this, M, FS), - DataLayout("E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-i64:64:64-f32:32:32" - "-f64:64:64-f128:128:128-a0:16:16"), - InstrInfo(*this), TLInfo(*this), - FrameInfo(TargetFrameInfo::StackGrowsDown, 8, -160) { + SystemZTargetMachine &getSystemZTargetMachine() const { + return getTM(); + } - if (getRelocationModel() == Reloc::Default) - setRelocationModel(Reloc::Static); + void addIRPasses() override; + bool addInstSelector() override; + bool addPreSched2() override; + bool addPreEmitPass() override; +}; +} // end anonymous namespace + +void SystemZPassConfig::addIRPasses() { + TargetPassConfig::addIRPasses(); } -bool SystemZTargetMachine::addInstSelector(PassManagerBase &PM, - CodeGenOpt::Level OptLevel) { - // Install an instruction selector. - PM.add(createSystemZISelDag(*this, OptLevel)); +bool SystemZPassConfig::addInstSelector() { + addPass(createSystemZISelDag(getSystemZTargetMachine(), getOptLevel())); return false; } -unsigned SystemZTargetMachine::getModuleMatchQuality(const Module &M) { - std::string TT = M.getTargetTriple(); +bool SystemZPassConfig::addPreSched2() { + if (getOptLevel() != CodeGenOpt::None && + getSystemZTargetMachine().getSubtargetImpl()->hasLoadStoreOnCond()) + addPass(&IfConverterID); + return true; +} - // We strongly match s390x - if (TT.size() >= 5 && TT[0] == 's' && TT[1] == '3' && TT[2] == '9' && - TT[3] == '0' && TT[4] == 'x') - return 20; +bool SystemZPassConfig::addPreEmitPass() { + // We eliminate comparisons here rather than earlier because some + // transformations can change the set of available CC values and we + // generally want those transformations to have priority. This is + // especially true in the commonest case where the result of the comparison + // is used by a single in-range branch instruction, since we will then + // be able to fuse the compare and the branch instead. + // + // For example, two-address NILF can sometimes be converted into + // three-address RISBLG. NILF produces a CC value that indicates whether + // the low word is zero, but RISBLG does not modify CC at all. On the + // other hand, 64-bit ANDs like NILL can sometimes be converted to RISBG. + // The CC value produced by NILL isn't useful for our purposes, but the + // value produced by RISBG can be used for any comparison with zero + // (not just equality). So there are some transformations that lose + // CC values (while still being worthwhile) and others that happen to make + // the CC result more useful than it was originally. + // + // Another reason is that we only want to use BRANCH ON COUNT in cases + // where we know that the count register is not going to be spilled. + // + // Doing it so late makes it more likely that a register will be reused + // between the comparison and the branch, but it isn't clear whether + // preventing that would be a win or not. + if (getOptLevel() != CodeGenOpt::None) + addPass(createSystemZElimComparePass(getSystemZTargetMachine())); + if (getOptLevel() != CodeGenOpt::None) + addPass(createSystemZShortenInstPass(getSystemZTargetMachine())); + addPass(createSystemZLongBranchPass(getSystemZTargetMachine())); + return true; +} - return 0; +TargetPassConfig *SystemZTargetMachine::createPassConfig(PassManagerBase &PM) { + return new SystemZPassConfig(this, PM); }