LLVM API Documentation
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"), DataLayout("e"), 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