LLVM API Documentation

IA64TargetMachine.cpp

Go to the documentation of this file.
00001 //===-- IA64TargetMachine.cpp - Define TargetMachine for IA64 -------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by Duraid Madina and is distributed under the
00006 // University of Illinois Open Source License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines the IA64 specific subclass of TargetMachine.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "IA64TargetMachine.h"
00015 #include "IA64.h"
00016 #include "llvm/Module.h"
00017 #include "llvm/PassManager.h"
00018 #include "llvm/CodeGen/MachineFunction.h"
00019 #include "llvm/CodeGen/Passes.h"
00020 #include "llvm/Target/TargetOptions.h"
00021 #include "llvm/Target/TargetMachineRegistry.h"
00022 #include "llvm/Transforms/Scalar.h"
00023 #include "llvm/Support/CommandLine.h"
00024 #include "llvm/ADT/Statistic.h"
00025 #include <iostream>
00026 using namespace llvm;
00027 
00028 /// IA64TargetMachineModule - Note that this is used on hosts that cannot link
00029 /// in a library unless there are references into the library.  In particular,
00030 /// it seems that it is not possible to get things to work on Win32 without
00031 /// this.  Though it is unused, do not remove it.
00032 extern "C" int IA64TargetMachineModule;
00033 int IA64TargetMachineModule = 0;
00034 
00035 namespace {
00036   cl::opt<bool> DisableOutput("disable-ia64-llc-output", cl::Hidden,
00037                               cl::desc("Disable the IA64 asm printer, for use "
00038                                        "when profiling the code generator."));
00039 
00040   cl::opt<bool> EnableDAGIsel("enable-ia64-dag-isel", cl::Hidden,
00041                   cl::desc("Enable the IA64 DAG->DAG isel"));
00042 
00043   // Register the target.
00044   RegisterTarget<IA64TargetMachine> X("ia64", "  IA-64 (Itanium)");
00045 }
00046 
00047 unsigned IA64TargetMachine::compileTimeMatchQuality() {
00048 #if defined(__ia64__) || defined(__IA64__)
00049   return 50;
00050 #else
00051   return 0;
00052 #endif
00053 }
00054 
00055 unsigned IA64TargetMachine::getModuleMatchQuality(const Module &M) {
00056   // we match [iI][aA]*64
00057   bool seenIA64=false;
00058   std::string TT = M.getTargetTriple();
00059 
00060   if (TT.size() >= 4) {
00061     if( (TT[0]=='i' || TT[0]=='I') &&
00062         (TT[1]=='a' || TT[1]=='A') ) {
00063       for(unsigned int i=2; i<(TT.size()-1); i++)
00064         if(TT[i]=='6' && TT[i+1]=='4')
00065           seenIA64=true;
00066     }
00067 
00068     if(seenIA64)
00069       return 50; // strong match
00070   }
00071 
00072   return compileTimeMatchQuality()/2;
00073 
00074 }
00075 
00076 /// IA64TargetMachine ctor - Create an LP64 architecture model
00077 ///
00078 IA64TargetMachine::IA64TargetMachine(const Module &M, const std::string &FS)
00079   : TargetMachine("IA64", true),
00080     FrameInfo(TargetFrameInfo::StackGrowsDown, 16, 0),
00081     TLInfo(*this) { // FIXME? check this stuff
00082 }
00083 
00084 // addPassesToEmitFile - We currently use all of the same passes as the JIT
00085 // does to emit statically compiled machine code.
00086 bool IA64TargetMachine::addPassesToEmitFile(PassManager &PM,
00087                                             std::ostream &Out,
00088                                             CodeGenFileType FileType,
00089                                             bool Fast) {
00090   if (FileType != TargetMachine::AssemblyFile) return true;
00091 
00092   // FIXME: Implement efficient support for garbage collection intrinsics.
00093   PM.add(createLowerGCPass());
00094 
00095   // FIXME: Implement the invoke/unwind instructions!
00096   PM.add(createLowerInvokePass(704, 16)); // on ia64 linux, jmpbufs are 704
00097                                           // bytes and must be 16byte aligned
00098 
00099   // Make sure that no unreachable blocks are instruction selected.
00100   PM.add(createUnreachableBlockEliminationPass());
00101 
00102   // Add an instruction selector
00103 // FIXME: reap this option one day:  if(EnableDAGIsel)
00104   PM.add(createIA64DAGToDAGInstructionSelector(*this));
00105   
00106 /* XXX not yet. ;)
00107   // Run optional SSA-based machine code optimizations next...
00108   if (!NoSSAPeephole)
00109     PM.add(createIA64SSAPeepholeOptimizerPass());
00110 */
00111 
00112   // Print the instruction selected machine code...
00113   if (PrintMachineCode)
00114     PM.add(createMachineFunctionPrinterPass(&std::cerr));
00115 
00116   // Perform register allocation to convert to a concrete IA64 representation
00117   PM.add(createRegisterAllocator());
00118 
00119   if (PrintMachineCode)
00120     PM.add(createMachineFunctionPrinterPass(&std::cerr));
00121 
00122   if (PrintMachineCode)
00123     PM.add(createMachineFunctionPrinterPass(&std::cerr));
00124 
00125   // Insert prolog/epilog code.  Eliminate abstract frame index references...
00126   PM.add(createPrologEpilogCodeInserter());
00127 
00128 /* XXX no, not just yet */
00129 //  PM.add(createIA64PeepholeOptimizerPass());
00130 
00131   // Make sure everything is bundled happily
00132   PM.add(createIA64BundlingPass(*this));
00133 
00134   if (PrintMachineCode)  // Print the register-allocated code
00135     PM.add(createIA64CodePrinterPass(std::cerr, *this));
00136 
00137   if (!DisableOutput)
00138     PM.add(createIA64CodePrinterPass(Out, *this));
00139 
00140   // Delete machine code for this function
00141   PM.add(createMachineCodeDeleter());
00142 
00143   return false; // success!
00144 }
00145