LLVM API Documentation

HexagonSplitConst32AndConst64.cpp
Go to the documentation of this file.
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 }