Make tail merging the default, except on powerPC. There was no prior art
[oota-llvm.git] / lib / Target / PowerPC / PPCTargetMachine.cpp
index 60ddcde57abafc692d2da96f8575affa071667a0..6d5e05077379e0980f923dc22b79d3ed2a6415f7 100644 (file)
-//===-- PowerPCTargetMachine.cpp - Define TargetMachine for PowerPC -------===//
-// 
+//===-- PPCTargetMachine.cpp - Define TargetMachine for PowerPC -----------===//
+//
 //                     The LLVM Compiler Infrastructure
 //
 // This file was developed by the LLVM research group and is distributed under
 // the University of Illinois Open Source License. See LICENSE.TXT for details.
-// 
+//
 //===----------------------------------------------------------------------===//
-// 
+//
+// Top-level implementation for the PowerPC target.
 //
 //===----------------------------------------------------------------------===//
 
-#include "PowerPCTargetMachine.h"
-#include "PowerPC.h"
+#include "PPC.h"
+#include "PPCTargetAsmInfo.h"
+#include "PPCTargetMachine.h"
 #include "llvm/Module.h"
 #include "llvm/PassManager.h"
-#include "llvm/CodeGen/IntrinsicLowering.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/Target/TargetOptions.h"
 #include "llvm/Target/TargetMachineRegistry.h"
-#include "llvm/Transforms/Scalar.h"
-#include <iostream>
 using namespace llvm;
 
-PowerPCTargetMachine::PowerPCTargetMachine(const std::string &name,
-                                           IntrinsicLowering *IL,
-                                           const TargetData &TD,
-                                           const TargetFrameInfo &TFI,
-                                           const PowerPCJITInfo &TJI) 
-  : TargetMachine(name, IL, TD), FrameInfo(TFI), JITInfo(TJI) {}
-
-unsigned PowerPCTargetMachine::getJITMatchQuality() {
-#if defined(__POWERPC__) || defined (__ppc__) || defined(_POWER)
-  return 10;
-#else
+namespace {
+  // Register the targets
+  RegisterTarget<PPC32TargetMachine>
+  X("ppc32", "  PowerPC 32");
+  RegisterTarget<PPC64TargetMachine>
+  Y("ppc64", "  PowerPC 64");
+}
+
+const TargetAsmInfo *PPCTargetMachine::createTargetAsmInfo() const {
+  if (Subtarget.isDarwin())
+    return new DarwinTargetAsmInfo(*this);
+  else
+    return new LinuxTargetAsmInfo(*this);
+}
+
+unsigned PPC32TargetMachine::getJITMatchQuality() {
+#if defined(__POWERPC__) || defined (__ppc__) || defined(_POWER) || defined(__PPC__)
+  if (sizeof(void*) == 4)
+    return 10;
+#endif
   return 0;
+}
+unsigned PPC64TargetMachine::getJITMatchQuality() {
+#if defined(__POWERPC__) || defined (__ppc__) || defined(_POWER) || defined(__PPC__)
+  if (sizeof(void*) == 8)
+    return 10;
 #endif
+  return 0;
+}
+
+unsigned PPC32TargetMachine::getModuleMatchQuality(const Module &M) {
+  // We strongly match "powerpc-*".
+  std::string TT = M.getTargetTriple();
+  if (TT.size() >= 8 && std::string(TT.begin(), TT.begin()+8) == "powerpc-")
+    return 20;
+  
+  if (M.getEndianness()  == Module::BigEndian &&
+      M.getPointerSize() == Module::Pointer32)
+    return 10;                                   // Weak match
+  else if (M.getEndianness() != Module::AnyEndianness ||
+           M.getPointerSize() != Module::AnyPointerSize)
+    return 0;                                    // Match for some other target
+  
+  return getJITMatchQuality()/2;
+}
+
+unsigned PPC64TargetMachine::getModuleMatchQuality(const Module &M) {
+  // We strongly match "powerpc64-*".
+  std::string TT = M.getTargetTriple();
+  if (TT.size() >= 10 && std::string(TT.begin(), TT.begin()+10) == "powerpc64-")
+    return 20;
+  
+  if (M.getEndianness()  == Module::BigEndian &&
+      M.getPointerSize() == Module::Pointer64)
+    return 10;                                   // Weak match
+  else if (M.getEndianness() != Module::AnyEndianness ||
+           M.getPointerSize() != Module::AnyPointerSize)
+    return 0;                                    // Match for some other target
+  
+  return getJITMatchQuality()/2;
 }
 
-void PowerPCJITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
-  assert(0 && "Cannot execute PowerPCJITInfo::addPassesToJITCompile()");
+
+PPCTargetMachine::PPCTargetMachine(const Module &M, const std::string &FS,
+                                   bool is64Bit)
+  : Subtarget(*this, M, FS, is64Bit),
+    DataLayout(Subtarget.getTargetDataString()), InstrInfo(*this),
+    FrameInfo(*this, is64Bit), JITInfo(*this, is64Bit), TLInfo(*this),
+    InstrItins(Subtarget.getInstrItineraryData()), MachOWriterInfo(*this) {
+
+  if (getRelocationModel() == Reloc::Default)
+    if (Subtarget.isDarwin())
+      setRelocationModel(Reloc::DynamicNoPIC);
+    else
+      setRelocationModel(Reloc::Static);
 }
 
-void PowerPCJITInfo::replaceMachineCodeForFunction(void *Old, void *New) {
-  assert(0 && "Cannot execute PowerPCJITInfo::replaceMachineCodeForFunction()");
+/// Override this for PowerPC.  Tail merging happily breaks up instruction issue
+/// groups, which typically degrades performance.
+const bool PPCTargetMachine::DoTailMergeDefault() const { return false; }
+
+PPC32TargetMachine::PPC32TargetMachine(const Module &M, const std::string &FS) 
+  : PPCTargetMachine(M, FS, false) {
 }
 
-void *PowerPCJITInfo::getJITStubForFunction(Function *F, 
+
+PPC64TargetMachine::PPC64TargetMachine(const Module &M, const std::string &FS)
+  : PPCTargetMachine(M, FS, true) {
+}
+
+
+//===----------------------------------------------------------------------===//
+// Pass Pipeline Configuration
+//===----------------------------------------------------------------------===//
+
+bool PPCTargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) {
+  // Install an instruction selector.
+  PM.add(createPPCISelDag(*this));
+  return false;
+}
+
+bool PPCTargetMachine::addPreEmitPass(FunctionPassManager &PM, bool Fast) {
+  
+  // Must run branch selection immediately preceding the asm printer.
+  PM.add(createPPCBranchSelectionPass());
+  return false;
+}
+
+bool PPCTargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast, 
+                                          std::ostream &Out) {
+  PM.add(createPPCAsmPrinterPass(Out, *this));
+  return false;
+}
+
+bool PPCTargetMachine::addCodeEmitter(FunctionPassManager &PM, bool Fast,
+                                      MachineCodeEmitter &MCE) {
+  // The JIT should use the static relocation model in ppc32 mode, PIC in ppc64.
+  // FIXME: This should be moved to TargetJITInfo!!
+  if (Subtarget.isPPC64()) {
+    // We use PIC codegen in ppc64 mode, because otherwise we'd have to use many
+    // instructions to materialize arbitrary global variable + function +
+    // constant pool addresses.
+    setRelocationModel(Reloc::PIC_);
+  } else {
+    setRelocationModel(Reloc::Static);
+  }
+  
+  // Inform the subtarget that we are in JIT mode.  FIXME: does this break macho
+  // writing?
+  Subtarget.SetJITMode();
+  
+  // Machine code emitter pass for PowerPC.
+  PM.add(createPPCCodeEmitterPass(*this, MCE));
+  return false;
+}
+
+bool PPCTargetMachine::addSimpleCodeEmitter(FunctionPassManager &PM, bool Fast,
                                             MachineCodeEmitter &MCE) {
-  assert(0 && "Cannot execute PowerPCJITInfo::getJITStubForFunction()");
-  return 0;
+  // Machine code emitter pass for PowerPC.
+  PM.add(createPPCCodeEmitterPass(*this, MCE));
+  return false;
 }