LLVM API Documentation
00001 //=== HexagonSplitConst32AndConst64.cpp - split CONST32/Const64 into HI/LO ===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // When the compiler is invoked with no small data, for instance, with the -G0 00011 // command line option, then all CONST32_* opcodes should be broken down into 00012 // appropriate LO and HI instructions. This splitting is done by this pass. 00013 // The only reason this is not done in the DAG lowering itself is that there 00014 // is no simple way of getting the register allocator to allot the same hard 00015 // register to the result of LO and HI instructions. This pass is always 00016 // scheduled after register allocation. 00017 // 00018 //===----------------------------------------------------------------------===// 00019 00020 #include "HexagonMachineFunctionInfo.h" 00021 #include "HexagonSubtarget.h" 00022 #include "HexagonTargetMachine.h" 00023 #include "HexagonTargetObjectFile.h" 00024 #include "llvm/ADT/Statistic.h" 00025 #include "llvm/CodeGen/LatencyPriorityQueue.h" 00026 #include "llvm/CodeGen/MachineDominators.h" 00027 #include "llvm/CodeGen/MachineFunctionPass.h" 00028 #include "llvm/CodeGen/MachineInstrBuilder.h" 00029 #include "llvm/CodeGen/MachineLoopInfo.h" 00030 #include "llvm/CodeGen/MachineRegisterInfo.h" 00031 #include "llvm/CodeGen/Passes.h" 00032 #include "llvm/CodeGen/ScheduleDAGInstrs.h" 00033 #include "llvm/CodeGen/ScheduleHazardRecognizer.h" 00034 #include "llvm/CodeGen/SchedulerRegistry.h" 00035 #include "llvm/Support/CommandLine.h" 00036 #include "llvm/Support/Compiler.h" 00037 #include "llvm/Support/Debug.h" 00038 #include "llvm/Support/MathExtras.h" 00039 #include "llvm/Target/TargetInstrInfo.h" 00040 #include "llvm/Target/TargetMachine.h" 00041 #include "llvm/Target/TargetRegisterInfo.h" 00042 #include <map> 00043 00044 using namespace llvm; 00045 00046 #define DEBUG_TYPE "xfer" 00047 00048 namespace { 00049 00050 class HexagonSplitConst32AndConst64 : public MachineFunctionPass { 00051 const HexagonTargetMachine &QTM; 00052 00053 public: 00054 static char ID; 00055 HexagonSplitConst32AndConst64(const HexagonTargetMachine &TM) 00056 : MachineFunctionPass(ID), QTM(TM) {} 00057 00058 const char *getPassName() const override { 00059 return "Hexagon Split Const32s and Const64s"; 00060 } 00061 bool runOnMachineFunction(MachineFunction &Fn) override; 00062 }; 00063 00064 00065 char HexagonSplitConst32AndConst64::ID = 0; 00066 00067 00068 bool HexagonSplitConst32AndConst64::runOnMachineFunction(MachineFunction &Fn) { 00069 00070 const HexagonTargetObjectFile &TLOF = 00071 (const HexagonTargetObjectFile &)QTM.getSubtargetImpl() 00072 ->getTargetLowering() 00073 ->getObjFileLowering(); 00074 if (TLOF.IsSmallDataEnabled()) 00075 return true; 00076 00077 const TargetInstrInfo *TII = QTM.getSubtargetImpl()->getInstrInfo(); 00078 00079 // Loop over all of the basic blocks 00080 for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end(); 00081 MBBb != MBBe; ++MBBb) { 00082 MachineBasicBlock* MBB = MBBb; 00083 // Traverse the basic block 00084 MachineBasicBlock::iterator MII = MBB->begin(); 00085 MachineBasicBlock::iterator MIE = MBB->end (); 00086 while (MII != MIE) { 00087 MachineInstr *MI = MII; 00088 int Opc = MI->getOpcode(); 00089 if (Opc == Hexagon::CONST32_set) { 00090 int DestReg = MI->getOperand(0).getReg(); 00091 MachineOperand &Symbol = MI->getOperand (1); 00092 00093 BuildMI (*MBB, MII, MI->getDebugLoc(), 00094 TII->get(Hexagon::LO), DestReg).addOperand(Symbol); 00095 BuildMI (*MBB, MII, MI->getDebugLoc(), 00096 TII->get(Hexagon::HI), DestReg).addOperand(Symbol); 00097 // MBB->erase returns the iterator to the next instruction, which is the 00098 // one we want to process next 00099 MII = MBB->erase (MI); 00100 continue; 00101 } 00102 else if (Opc == Hexagon::CONST32_set_jt) { 00103 int DestReg = MI->getOperand(0).getReg(); 00104 MachineOperand &Symbol = MI->getOperand (1); 00105 00106 BuildMI (*MBB, MII, MI->getDebugLoc(), 00107 TII->get(Hexagon::LO_jt), DestReg).addOperand(Symbol); 00108 BuildMI (*MBB, MII, MI->getDebugLoc(), 00109 TII->get(Hexagon::HI_jt), DestReg).addOperand(Symbol); 00110 // MBB->erase returns the iterator to the next instruction, which is the 00111 // one we want to process next 00112 MII = MBB->erase (MI); 00113 continue; 00114 } 00115 else if (Opc == Hexagon::CONST32_Label) { 00116 int DestReg = MI->getOperand(0).getReg(); 00117 MachineOperand &Symbol = MI->getOperand (1); 00118 00119 BuildMI (*MBB, MII, MI->getDebugLoc(), 00120 TII->get(Hexagon::LO_label), DestReg).addOperand(Symbol); 00121 BuildMI (*MBB, MII, MI->getDebugLoc(), 00122 TII->get(Hexagon::HI_label), DestReg).addOperand(Symbol); 00123 // MBB->erase returns the iterator to the next instruction, which is the 00124 // one we want to process next 00125 MII = MBB->erase (MI); 00126 continue; 00127 } 00128 else if (Opc == Hexagon::CONST32_Int_Real) { 00129 int DestReg = MI->getOperand(0).getReg(); 00130 int64_t ImmValue = MI->getOperand(1).getImm (); 00131 00132 BuildMI (*MBB, MII, MI->getDebugLoc(), 00133 TII->get(Hexagon::LOi), DestReg).addImm(ImmValue); 00134 BuildMI (*MBB, MII, MI->getDebugLoc(), 00135 TII->get(Hexagon::HIi), DestReg).addImm(ImmValue); 00136 MII = MBB->erase (MI); 00137 continue; 00138 } 00139 else if (Opc == Hexagon::CONST64_Int_Real) { 00140 int DestReg = MI->getOperand(0).getReg(); 00141 int64_t ImmValue = MI->getOperand(1).getImm (); 00142 unsigned DestLo = QTM.getSubtargetImpl()->getRegisterInfo()->getSubReg( 00143 DestReg, Hexagon::subreg_loreg); 00144 unsigned DestHi = QTM.getSubtargetImpl()->getRegisterInfo()->getSubReg( 00145 DestReg, Hexagon::subreg_hireg); 00146 00147 int32_t LowWord = (ImmValue & 0xFFFFFFFF); 00148 int32_t HighWord = (ImmValue >> 32) & 0xFFFFFFFF; 00149 00150 // Lower Registers Lower Half 00151 BuildMI (*MBB, MII, MI->getDebugLoc(), 00152 TII->get(Hexagon::LOi), DestLo).addImm(LowWord); 00153 // Lower Registers Higher Half 00154 BuildMI (*MBB, MII, MI->getDebugLoc(), 00155 TII->get(Hexagon::HIi), DestLo).addImm(LowWord); 00156 // Higher Registers Lower Half 00157 BuildMI (*MBB, MII, MI->getDebugLoc(), 00158 TII->get(Hexagon::LOi), DestHi).addImm(HighWord); 00159 // Higher Registers Higher Half. 00160 BuildMI (*MBB, MII, MI->getDebugLoc(), 00161 TII->get(Hexagon::HIi), DestHi).addImm(HighWord); 00162 MII = MBB->erase (MI); 00163 continue; 00164 } 00165 ++MII; 00166 } 00167 } 00168 00169 return true; 00170 } 00171 00172 } 00173 00174 //===----------------------------------------------------------------------===// 00175 // Public Constructor Functions 00176 //===----------------------------------------------------------------------===// 00177 00178 FunctionPass * 00179 llvm::createHexagonSplitConst32AndConst64(const HexagonTargetMachine &TM) { 00180 return new HexagonSplitConst32AndConst64(TM); 00181 }