LLVM API Documentation

HexagonExpandPredSpillCode.cpp
Go to the documentation of this file.
00001 //===-- HexagonExpandPredSpillCode.cpp - Expand Predicate Spill Code ------===//
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 // The Hexagon processor has no instructions that load or store predicate
00010 // registers directly.  So, when these registers must be spilled a general
00011 // purpose register must be found and the value copied to/from it from/to
00012 // the predicate register.  This code currently does not use the register
00013 // scavenger mechanism available in the allocator.  There are two registers
00014 // reserved to allow spilling/restoring predicate registers.  One is used to
00015 // hold the predicate value.  The other is used when stack frame offsets are
00016 // too large.
00017 //
00018 //===----------------------------------------------------------------------===//
00019 
00020 #include "Hexagon.h"
00021 #include "HexagonMachineFunctionInfo.h"
00022 #include "HexagonSubtarget.h"
00023 #include "HexagonTargetMachine.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/ScheduleHazardRecognizer.h"
00033 #include "llvm/CodeGen/SchedulerRegistry.h"
00034 #include "llvm/Support/Compiler.h"
00035 #include "llvm/Support/Debug.h"
00036 #include "llvm/Support/MathExtras.h"
00037 #include "llvm/Target/TargetInstrInfo.h"
00038 #include "llvm/Target/TargetMachine.h"
00039 #include "llvm/Target/TargetRegisterInfo.h"
00040 
00041 using namespace llvm;
00042 
00043 
00044 namespace llvm {
00045   void initializeHexagonExpandPredSpillCodePass(PassRegistry&);
00046 }
00047 
00048 
00049 namespace {
00050 
00051 class HexagonExpandPredSpillCode : public MachineFunctionPass {
00052     const HexagonTargetMachine& QTM;
00053     const HexagonSubtarget &QST;
00054 
00055  public:
00056     static char ID;
00057     HexagonExpandPredSpillCode(const HexagonTargetMachine& TM) :
00058       MachineFunctionPass(ID), QTM(TM), QST(*TM.getSubtargetImpl()) {
00059       PassRegistry &Registry = *PassRegistry::getPassRegistry();
00060       initializeHexagonExpandPredSpillCodePass(Registry);
00061     }
00062 
00063     const char *getPassName() const override {
00064       return "Hexagon Expand Predicate Spill Code";
00065     }
00066     bool runOnMachineFunction(MachineFunction &Fn) override;
00067 };
00068 
00069 
00070 char HexagonExpandPredSpillCode::ID = 0;
00071 
00072 
00073 bool HexagonExpandPredSpillCode::runOnMachineFunction(MachineFunction &Fn) {
00074 
00075   const HexagonInstrInfo *TII = QTM.getSubtargetImpl()->getInstrInfo();
00076 
00077   // Loop over all of the basic blocks.
00078   for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end();
00079        MBBb != MBBe; ++MBBb) {
00080     MachineBasicBlock* MBB = MBBb;
00081     // Traverse the basic block.
00082     for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end();
00083          ++MII) {
00084       MachineInstr *MI = MII;
00085       int Opc = MI->getOpcode();
00086       if (Opc == Hexagon::STriw_pred) {
00087         // STriw_pred [R30], ofst, SrcReg;
00088         unsigned FP = MI->getOperand(0).getReg();
00089         assert(
00090             FP ==
00091                 QTM.getSubtargetImpl()->getRegisterInfo()->getFrameRegister() &&
00092             "Not a Frame Pointer, Nor a Spill Slot");
00093         assert(MI->getOperand(1).isImm() && "Not an offset");
00094         int Offset = MI->getOperand(1).getImm();
00095         int SrcReg = MI->getOperand(2).getReg();
00096         assert(Hexagon::PredRegsRegClass.contains(SrcReg) &&
00097                "Not a predicate register");
00098         if (!TII->isValidOffset(Hexagon::STriw_indexed, Offset)) {
00099           if (!TII->isValidOffset(Hexagon::ADD_ri, Offset)) {
00100             BuildMI(*MBB, MII, MI->getDebugLoc(),
00101                     TII->get(Hexagon::CONST32_Int_Real),
00102                       HEXAGON_RESERVED_REG_1).addImm(Offset);
00103             BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_rr),
00104                     HEXAGON_RESERVED_REG_1)
00105               .addReg(FP).addReg(HEXAGON_RESERVED_REG_1);
00106             BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd),
00107                       HEXAGON_RESERVED_REG_2).addReg(SrcReg);
00108             BuildMI(*MBB, MII, MI->getDebugLoc(),
00109                     TII->get(Hexagon::STriw_indexed))
00110               .addReg(HEXAGON_RESERVED_REG_1)
00111               .addImm(0).addReg(HEXAGON_RESERVED_REG_2);
00112           } else {
00113             BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_ri),
00114                       HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset);
00115             BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd),
00116                       HEXAGON_RESERVED_REG_2).addReg(SrcReg);
00117             BuildMI(*MBB, MII, MI->getDebugLoc(),
00118                           TII->get(Hexagon::STriw_indexed))
00119               .addReg(HEXAGON_RESERVED_REG_1)
00120               .addImm(0)
00121               .addReg(HEXAGON_RESERVED_REG_2);
00122           }
00123         } else {
00124           BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd),
00125                     HEXAGON_RESERVED_REG_2).addReg(SrcReg);
00126           BuildMI(*MBB, MII, MI->getDebugLoc(),
00127                         TII->get(Hexagon::STriw_indexed)).
00128                     addReg(FP).addImm(Offset).addReg(HEXAGON_RESERVED_REG_2);
00129         }
00130         MII = MBB->erase(MI);
00131         --MII;
00132       } else if (Opc == Hexagon::LDriw_pred) {
00133         // DstReg = LDriw_pred [R30], ofst.
00134         int DstReg = MI->getOperand(0).getReg();
00135         assert(Hexagon::PredRegsRegClass.contains(DstReg) &&
00136                "Not a predicate register");
00137         unsigned FP = MI->getOperand(1).getReg();
00138         assert(
00139             FP ==
00140                 QTM.getSubtargetImpl()->getRegisterInfo()->getFrameRegister() &&
00141             "Not a Frame Pointer, Nor a Spill Slot");
00142         assert(MI->getOperand(2).isImm() && "Not an offset");
00143         int Offset = MI->getOperand(2).getImm();
00144         if (!TII->isValidOffset(Hexagon::LDriw, Offset)) {
00145           if (!TII->isValidOffset(Hexagon::ADD_ri, Offset)) {
00146             BuildMI(*MBB, MII, MI->getDebugLoc(),
00147                     TII->get(Hexagon::CONST32_Int_Real),
00148                       HEXAGON_RESERVED_REG_1).addImm(Offset);
00149             BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_rr),
00150                     HEXAGON_RESERVED_REG_1)
00151               .addReg(FP)
00152               .addReg(HEXAGON_RESERVED_REG_1);
00153             BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::LDriw),
00154                       HEXAGON_RESERVED_REG_2)
00155               .addReg(HEXAGON_RESERVED_REG_1)
00156               .addImm(0);
00157             BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_PdRs),
00158                       DstReg).addReg(HEXAGON_RESERVED_REG_2);
00159           } else {
00160             BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_ri),
00161                       HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset);
00162             BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::LDriw),
00163                       HEXAGON_RESERVED_REG_2)
00164               .addReg(HEXAGON_RESERVED_REG_1)
00165               .addImm(0);
00166             BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_PdRs),
00167                       DstReg).addReg(HEXAGON_RESERVED_REG_2);
00168           }
00169         } else {
00170           BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::LDriw),
00171                     HEXAGON_RESERVED_REG_2).addReg(FP).addImm(Offset);
00172           BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_PdRs),
00173                     DstReg).addReg(HEXAGON_RESERVED_REG_2);
00174         }
00175         MII = MBB->erase(MI);
00176         --MII;
00177       }
00178     }
00179   }
00180 
00181   return true;
00182 }
00183 
00184 }
00185 
00186 //===----------------------------------------------------------------------===//
00187 //                         Public Constructor Functions
00188 //===----------------------------------------------------------------------===//
00189 
00190 static void initializePassOnce(PassRegistry &Registry) {
00191   const char *Name = "Hexagon Expand Predicate Spill Code";
00192   PassInfo *PI = new PassInfo(Name, "hexagon-spill-pred",
00193                               &HexagonExpandPredSpillCode::ID,
00194                               nullptr, false, false);
00195   Registry.registerPass(*PI, true);
00196 }
00197 
00198 void llvm::initializeHexagonExpandPredSpillCodePass(PassRegistry &Registry) {
00199   CALL_ONCE_INITIALIZATION(initializePassOnce)
00200 }
00201 
00202 FunctionPass*
00203 llvm::createHexagonExpandPredSpillCode(const HexagonTargetMachine &TM) {
00204   return new HexagonExpandPredSpillCode(TM);
00205 }