Home | History | Annotate | Download | only in Hexagon
      1 //===-- HexagonExpandPredSpillCode.cpp - Expand Predicate Spill Code ------===//
      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 // The Hexagon processor has no instructions that load or store predicate
     10 // registers directly.  So, when these registers must be spilled a general
     11 // purpose register must be found and the value copied to/from it from/to
     12 // the predicate register.  This code currently does not use the register
     13 // scavenger mechanism available in the allocator.  There are two registers
     14 // reserved to allow spilling/restoring predicate registers.  One is used to
     15 // hold the predicate value.  The other is used when stack frame offsets are
     16 // too large.
     17 //
     18 //===----------------------------------------------------------------------===//
     19 
     20 #include "Hexagon.h"
     21 #include "HexagonMachineFunctionInfo.h"
     22 #include "HexagonSubtarget.h"
     23 #include "HexagonTargetMachine.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/ScheduleHazardRecognizer.h"
     33 #include "llvm/CodeGen/SchedulerRegistry.h"
     34 #include "llvm/Support/Compiler.h"
     35 #include "llvm/Support/Debug.h"
     36 #include "llvm/Support/MathExtras.h"
     37 #include "llvm/Target/TargetInstrInfo.h"
     38 #include "llvm/Target/TargetMachine.h"
     39 #include "llvm/Target/TargetRegisterInfo.h"
     40 
     41 using namespace llvm;
     42 
     43 
     44 namespace llvm {
     45   void initializeHexagonExpandPredSpillCodePass(PassRegistry&);
     46 }
     47 
     48 
     49 namespace {
     50 
     51 class HexagonExpandPredSpillCode : public MachineFunctionPass {
     52     const HexagonTargetMachine& QTM;
     53     const HexagonSubtarget &QST;
     54 
     55  public:
     56     static char ID;
     57     HexagonExpandPredSpillCode(const HexagonTargetMachine& TM) :
     58       MachineFunctionPass(ID), QTM(TM), QST(*TM.getSubtargetImpl()) {
     59       PassRegistry &Registry = *PassRegistry::getPassRegistry();
     60       initializeHexagonExpandPredSpillCodePass(Registry);
     61     }
     62 
     63     const char *getPassName() const {
     64       return "Hexagon Expand Predicate Spill Code";
     65     }
     66     bool runOnMachineFunction(MachineFunction &Fn);
     67 };
     68 
     69 
     70 char HexagonExpandPredSpillCode::ID = 0;
     71 
     72 
     73 bool HexagonExpandPredSpillCode::runOnMachineFunction(MachineFunction &Fn) {
     74 
     75   const HexagonInstrInfo *TII = QTM.getInstrInfo();
     76 
     77   // Loop over all of the basic blocks.
     78   for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end();
     79        MBBb != MBBe; ++MBBb) {
     80     MachineBasicBlock* MBB = MBBb;
     81     // Traverse the basic block.
     82     for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end();
     83          ++MII) {
     84       MachineInstr *MI = MII;
     85       int Opc = MI->getOpcode();
     86       if (Opc == Hexagon::STriw_pred) {
     87         // STriw_pred [R30], ofst, SrcReg;
     88         unsigned FP = MI->getOperand(0).getReg();
     89         assert(FP == QTM.getRegisterInfo()->getFrameRegister() &&
     90                "Not a Frame Pointer, Nor a Spill Slot");
     91         assert(MI->getOperand(1).isImm() && "Not an offset");
     92         int Offset = MI->getOperand(1).getImm();
     93         int SrcReg = MI->getOperand(2).getReg();
     94         assert(Hexagon::PredRegsRegClass.contains(SrcReg) &&
     95                "Not a predicate register");
     96         if (!TII->isValidOffset(Hexagon::STriw_indexed, Offset)) {
     97           if (!TII->isValidOffset(Hexagon::ADD_ri, Offset)) {
     98             BuildMI(*MBB, MII, MI->getDebugLoc(),
     99                     TII->get(Hexagon::CONST32_Int_Real),
    100                       HEXAGON_RESERVED_REG_1).addImm(Offset);
    101             BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_rr),
    102                     HEXAGON_RESERVED_REG_1)
    103               .addReg(FP).addReg(HEXAGON_RESERVED_REG_1);
    104             BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd),
    105                       HEXAGON_RESERVED_REG_2).addReg(SrcReg);
    106             BuildMI(*MBB, MII, MI->getDebugLoc(),
    107                     TII->get(Hexagon::STriw_indexed))
    108               .addReg(HEXAGON_RESERVED_REG_1)
    109               .addImm(0).addReg(HEXAGON_RESERVED_REG_2);
    110           } else {
    111             BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_ri),
    112                       HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset);
    113             BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd),
    114                       HEXAGON_RESERVED_REG_2).addReg(SrcReg);
    115             BuildMI(*MBB, MII, MI->getDebugLoc(),
    116                           TII->get(Hexagon::STriw_indexed))
    117               .addReg(HEXAGON_RESERVED_REG_1)
    118               .addImm(0)
    119               .addReg(HEXAGON_RESERVED_REG_2);
    120           }
    121         } else {
    122           BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd),
    123                     HEXAGON_RESERVED_REG_2).addReg(SrcReg);
    124           BuildMI(*MBB, MII, MI->getDebugLoc(),
    125                         TII->get(Hexagon::STriw_indexed)).
    126                     addReg(FP).addImm(Offset).addReg(HEXAGON_RESERVED_REG_2);
    127         }
    128         MII = MBB->erase(MI);
    129         --MII;
    130       } else if (Opc == Hexagon::LDriw_pred) {
    131         // DstReg = LDriw_pred [R30], ofst.
    132         int DstReg = MI->getOperand(0).getReg();
    133         assert(Hexagon::PredRegsRegClass.contains(DstReg) &&
    134                "Not a predicate register");
    135         unsigned FP = MI->getOperand(1).getReg();
    136         assert(FP == QTM.getRegisterInfo()->getFrameRegister() &&
    137                "Not a Frame Pointer, Nor a Spill Slot");
    138         assert(MI->getOperand(2).isImm() && "Not an offset");
    139         int Offset = MI->getOperand(2).getImm();
    140         if (!TII->isValidOffset(Hexagon::LDriw, Offset)) {
    141           if (!TII->isValidOffset(Hexagon::ADD_ri, Offset)) {
    142             BuildMI(*MBB, MII, MI->getDebugLoc(),
    143                     TII->get(Hexagon::CONST32_Int_Real),
    144                       HEXAGON_RESERVED_REG_1).addImm(Offset);
    145             BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_rr),
    146                     HEXAGON_RESERVED_REG_1)
    147               .addReg(FP)
    148               .addReg(HEXAGON_RESERVED_REG_1);
    149             BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::LDriw),
    150                       HEXAGON_RESERVED_REG_2)
    151               .addReg(HEXAGON_RESERVED_REG_1)
    152               .addImm(0);
    153             BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_PdRs),
    154                       DstReg).addReg(HEXAGON_RESERVED_REG_2);
    155           } else {
    156             BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_ri),
    157                       HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset);
    158             BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::LDriw),
    159                       HEXAGON_RESERVED_REG_2)
    160               .addReg(HEXAGON_RESERVED_REG_1)
    161               .addImm(0);
    162             BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_PdRs),
    163                       DstReg).addReg(HEXAGON_RESERVED_REG_2);
    164           }
    165         } else {
    166           BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::LDriw),
    167                     HEXAGON_RESERVED_REG_2).addReg(FP).addImm(Offset);
    168           BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_PdRs),
    169                     DstReg).addReg(HEXAGON_RESERVED_REG_2);
    170         }
    171         MII = MBB->erase(MI);
    172         --MII;
    173       }
    174     }
    175   }
    176 
    177   return true;
    178 }
    179 
    180 }
    181 
    182 //===----------------------------------------------------------------------===//
    183 //                         Public Constructor Functions
    184 //===----------------------------------------------------------------------===//
    185 
    186 static void initializePassOnce(PassRegistry &Registry) {
    187   const char *Name = "Hexagon Expand Predicate Spill Code";
    188   PassInfo *PI = new PassInfo(Name, "hexagon-spill-pred",
    189                               &HexagonExpandPredSpillCode::ID,
    190                               0, false, false);
    191   Registry.registerPass(*PI, true);
    192 }
    193 
    194 void llvm::initializeHexagonExpandPredSpillCodePass(PassRegistry &Registry) {
    195   CALL_ONCE_INITIALIZATION(initializePassOnce)
    196 }
    197 
    198 FunctionPass*
    199 llvm::createHexagonExpandPredSpillCode(const HexagonTargetMachine &TM) {
    200   return new HexagonExpandPredSpillCode(TM);
    201 }
    202