Home | History | Annotate | Download | only in Hexagon
      1 //=== HexagonSplitConst32AndConst64.cpp - split CONST32/Const64 into HI/LO ===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // When the compiler is invoked with no small data, for instance, with the -G0
     11 // command line option, then all CONST32_* opcodes should be broken down into
     12 // appropriate LO and HI instructions. This splitting is done by this pass.
     13 // The only reason this is not done in the DAG lowering itself is that there
     14 // is no simple way of getting the register allocator to allot the same hard
     15 // register to the result of LO and HI instructions. This pass is always
     16 // scheduled after register allocation.
     17 //
     18 //===----------------------------------------------------------------------===//
     19 
     20 #include "HexagonMachineFunctionInfo.h"
     21 #include "HexagonSubtarget.h"
     22 #include "HexagonTargetMachine.h"
     23 #include "HexagonTargetObjectFile.h"
     24 #include "llvm/ADT/Statistic.h"
     25 #include "llvm/CodeGen/LatencyPriorityQueue.h"
     26 #include "llvm/CodeGen/MachineDominators.h"
     27 #include "llvm/CodeGen/MachineFunctionPass.h"
     28 #include "llvm/CodeGen/MachineInstrBuilder.h"
     29 #include "llvm/CodeGen/MachineLoopInfo.h"
     30 #include "llvm/CodeGen/MachineRegisterInfo.h"
     31 #include "llvm/CodeGen/Passes.h"
     32 #include "llvm/CodeGen/ScheduleDAGInstrs.h"
     33 #include "llvm/CodeGen/ScheduleHazardRecognizer.h"
     34 #include "llvm/CodeGen/SchedulerRegistry.h"
     35 #include "llvm/Support/CommandLine.h"
     36 #include "llvm/Support/Compiler.h"
     37 #include "llvm/Support/Debug.h"
     38 #include "llvm/Support/MathExtras.h"
     39 #include "llvm/Target/TargetInstrInfo.h"
     40 #include "llvm/Target/TargetMachine.h"
     41 #include "llvm/Target/TargetRegisterInfo.h"
     42 #include <map>
     43 
     44 using namespace llvm;
     45 
     46 #define DEBUG_TYPE "xfer"
     47 
     48 namespace {
     49 
     50 class HexagonSplitConst32AndConst64 : public MachineFunctionPass {
     51   const HexagonTargetMachine &QTM;
     52 
     53  public:
     54     static char ID;
     55     HexagonSplitConst32AndConst64(const HexagonTargetMachine &TM)
     56         : MachineFunctionPass(ID), QTM(TM) {}
     57 
     58     const char *getPassName() const override {
     59       return "Hexagon Split Const32s and Const64s";
     60     }
     61     bool runOnMachineFunction(MachineFunction &Fn) override;
     62 };
     63 
     64 
     65 char HexagonSplitConst32AndConst64::ID = 0;
     66 
     67 
     68 bool HexagonSplitConst32AndConst64::runOnMachineFunction(MachineFunction &Fn) {
     69 
     70   const HexagonTargetObjectFile &TLOF =
     71       (const HexagonTargetObjectFile &)
     72       QTM.getTargetLowering()->getObjFileLowering();
     73   if (TLOF.IsSmallDataEnabled())
     74     return true;
     75 
     76   const TargetInstrInfo *TII = QTM.getInstrInfo();
     77 
     78   // Loop over all of the basic blocks
     79   for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end();
     80        MBBb != MBBe; ++MBBb) {
     81     MachineBasicBlock* MBB = MBBb;
     82     // Traverse the basic block
     83     MachineBasicBlock::iterator MII = MBB->begin();
     84     MachineBasicBlock::iterator MIE = MBB->end ();
     85     while (MII != MIE) {
     86       MachineInstr *MI = MII;
     87       int Opc = MI->getOpcode();
     88       if (Opc == Hexagon::CONST32_set) {
     89         int DestReg = MI->getOperand(0).getReg();
     90         MachineOperand &Symbol = MI->getOperand (1);
     91 
     92         BuildMI (*MBB, MII, MI->getDebugLoc(),
     93                  TII->get(Hexagon::LO), DestReg).addOperand(Symbol);
     94         BuildMI (*MBB, MII, MI->getDebugLoc(),
     95                  TII->get(Hexagon::HI), DestReg).addOperand(Symbol);
     96         // MBB->erase returns the iterator to the next instruction, which is the
     97         // one we want to process next
     98         MII = MBB->erase (MI);
     99         continue;
    100       }
    101       else if (Opc == Hexagon::CONST32_set_jt) {
    102         int DestReg = MI->getOperand(0).getReg();
    103         MachineOperand &Symbol = MI->getOperand (1);
    104 
    105         BuildMI (*MBB, MII, MI->getDebugLoc(),
    106                  TII->get(Hexagon::LO_jt), DestReg).addOperand(Symbol);
    107         BuildMI (*MBB, MII, MI->getDebugLoc(),
    108                  TII->get(Hexagon::HI_jt), DestReg).addOperand(Symbol);
    109         // MBB->erase returns the iterator to the next instruction, which is the
    110         // one we want to process next
    111         MII = MBB->erase (MI);
    112         continue;
    113       }
    114       else if (Opc == Hexagon::CONST32_Label) {
    115         int DestReg = MI->getOperand(0).getReg();
    116         MachineOperand &Symbol = MI->getOperand (1);
    117 
    118         BuildMI (*MBB, MII, MI->getDebugLoc(),
    119                  TII->get(Hexagon::LO_label), DestReg).addOperand(Symbol);
    120         BuildMI (*MBB, MII, MI->getDebugLoc(),
    121                  TII->get(Hexagon::HI_label), DestReg).addOperand(Symbol);
    122         // MBB->erase returns the iterator to the next instruction, which is the
    123         // one we want to process next
    124         MII = MBB->erase (MI);
    125         continue;
    126       }
    127       else if (Opc == Hexagon::CONST32_Int_Real) {
    128         int DestReg = MI->getOperand(0).getReg();
    129         int64_t ImmValue = MI->getOperand(1).getImm ();
    130 
    131         BuildMI (*MBB, MII, MI->getDebugLoc(),
    132                  TII->get(Hexagon::LOi), DestReg).addImm(ImmValue);
    133         BuildMI (*MBB, MII, MI->getDebugLoc(),
    134                  TII->get(Hexagon::HIi), DestReg).addImm(ImmValue);
    135         MII = MBB->erase (MI);
    136         continue;
    137       }
    138       else if (Opc == Hexagon::CONST64_Int_Real) {
    139         int DestReg = MI->getOperand(0).getReg();
    140         int64_t ImmValue = MI->getOperand(1).getImm ();
    141         unsigned DestLo =
    142           QTM.getRegisterInfo()->getSubReg (DestReg, Hexagon::subreg_loreg);
    143         unsigned DestHi =
    144           QTM.getRegisterInfo()->getSubReg (DestReg, Hexagon::subreg_hireg);
    145 
    146         int32_t LowWord = (ImmValue & 0xFFFFFFFF);
    147         int32_t HighWord = (ImmValue >> 32) & 0xFFFFFFFF;
    148 
    149         // Lower Registers Lower Half
    150         BuildMI (*MBB, MII, MI->getDebugLoc(),
    151                  TII->get(Hexagon::LOi), DestLo).addImm(LowWord);
    152         // Lower Registers Higher Half
    153         BuildMI (*MBB, MII, MI->getDebugLoc(),
    154                  TII->get(Hexagon::HIi), DestLo).addImm(LowWord);
    155         // Higher Registers Lower Half
    156         BuildMI (*MBB, MII, MI->getDebugLoc(),
    157                  TII->get(Hexagon::LOi), DestHi).addImm(HighWord);
    158         // Higher Registers Higher Half.
    159         BuildMI (*MBB, MII, MI->getDebugLoc(),
    160                  TII->get(Hexagon::HIi), DestHi).addImm(HighWord);
    161         MII = MBB->erase (MI);
    162         continue;
    163        }
    164       ++MII;
    165     }
    166   }
    167 
    168   return true;
    169 }
    170 
    171 }
    172 
    173 //===----------------------------------------------------------------------===//
    174 //                         Public Constructor Functions
    175 //===----------------------------------------------------------------------===//
    176 
    177 FunctionPass *
    178 llvm::createHexagonSplitConst32AndConst64(const HexagonTargetMachine &TM) {
    179   return new HexagonSplitConst32AndConst64(TM);
    180 }
    181