HexagonExpandPredSpillCode.cpp revision 249423
1251875Speter//===-- HexagonExpandPredSpillCode.cpp - Expand Predicate Spill Code ------===// 2251875Speter// 3251875Speter// The LLVM Compiler Infrastructure 4251875Speter// 5251875Speter// This file is distributed under the University of Illinois Open Source 6251875Speter// License. See LICENSE.TXT for details. 7251875Speter// 8251875Speter//===----------------------------------------------------------------------===// 9251875Speter// The Hexagon processor has no instructions that load or store predicate 10251875Speter// registers directly. So, when these registers must be spilled a general 11251875Speter// purpose register must be found and the value copied to/from it from/to 12251875Speter// the predicate register. This code currently does not use the register 13251875Speter// scavenger mechanism available in the allocator. There are two registers 14251875Speter// reserved to allow spilling/restoring predicate registers. One is used to 15251875Speter// hold the predicate value. The other is used when stack frame offsets are 16251875Speter// too large. 17251875Speter// 18251875Speter//===----------------------------------------------------------------------===// 19251875Speter 20251875Speter#include "Hexagon.h" 21251875Speter#include "HexagonMachineFunctionInfo.h" 22251875Speter#include "HexagonSubtarget.h" 23251875Speter#include "HexagonTargetMachine.h" 24251875Speter#include "llvm/ADT/Statistic.h" 25251875Speter#include "llvm/CodeGen/LatencyPriorityQueue.h" 26251875Speter#include "llvm/CodeGen/MachineDominators.h" 27251875Speter#include "llvm/CodeGen/MachineFunctionPass.h" 28251875Speter#include "llvm/CodeGen/MachineInstrBuilder.h" 29251875Speter#include "llvm/CodeGen/MachineLoopInfo.h" 30251875Speter#include "llvm/CodeGen/MachineRegisterInfo.h" 31251875Speter#include "llvm/CodeGen/Passes.h" 32251875Speter#include "llvm/CodeGen/ScheduleHazardRecognizer.h" 33251875Speter#include "llvm/CodeGen/SchedulerRegistry.h" 34251875Speter#include "llvm/Support/Compiler.h" 35251875Speter#include "llvm/Support/Debug.h" 36251875Speter#include "llvm/Support/MathExtras.h" 37251875Speter#include "llvm/Target/TargetInstrInfo.h" 38251875Speter#include "llvm/Target/TargetMachine.h" 39251875Speter#include "llvm/Target/TargetRegisterInfo.h" 40251875Speter 41251875Speterusing namespace llvm; 42251875Speter 43251875Speter 44251875Speternamespace { 45251875Speter 46269847Speterclass HexagonExpandPredSpillCode : public MachineFunctionPass { 47269847Speter HexagonTargetMachine& QTM; 48251875Speter const HexagonSubtarget &QST; 49251875Speter 50251875Speter public: 51251875Speter static char ID; 52251875Speter HexagonExpandPredSpillCode(HexagonTargetMachine& TM) : 53251875Speter MachineFunctionPass(ID), QTM(TM), QST(*TM.getSubtargetImpl()) {} 54251875Speter 55251875Speter const char *getPassName() const { 56251875Speter return "Hexagon Expand Predicate Spill Code"; 57251875Speter } 58251875Speter bool runOnMachineFunction(MachineFunction &Fn); 59251875Speter}; 60251875Speter 61251875Speter 62251875Speterchar HexagonExpandPredSpillCode::ID = 0; 63251875Speter 64251875Speter 65251875Speterbool HexagonExpandPredSpillCode::runOnMachineFunction(MachineFunction &Fn) { 66251875Speter 67251875Speter const HexagonInstrInfo *TII = QTM.getInstrInfo(); 68251875Speter 69251875Speter // Loop over all of the basic blocks. 70251875Speter for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end(); 71251875Speter MBBb != MBBe; ++MBBb) { 72251875Speter MachineBasicBlock* MBB = MBBb; 73251875Speter // Traverse the basic block. 74251875Speter for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end(); 75269847Speter ++MII) { 76269847Speter MachineInstr *MI = MII; 77269847Speter int Opc = MI->getOpcode(); 78269847Speter if (Opc == Hexagon::STriw_pred) { 79269847Speter // STriw_pred [R30], ofst, SrcReg; 80269847Speter unsigned FP = MI->getOperand(0).getReg(); 81269847Speter assert(FP == QTM.getRegisterInfo()->getFrameRegister() && 82269847Speter "Not a Frame Pointer, Nor a Spill Slot"); 83269847Speter assert(MI->getOperand(1).isImm() && "Not an offset"); 84269847Speter int Offset = MI->getOperand(1).getImm(); 85269847Speter int SrcReg = MI->getOperand(2).getReg(); 86269847Speter assert(Hexagon::PredRegsRegClass.contains(SrcReg) && 87269847Speter "Not a predicate register"); 88269847Speter if (!TII->isValidOffset(Hexagon::STriw_indexed, Offset)) { 89269847Speter if (!TII->isValidOffset(Hexagon::ADD_ri, Offset)) { 90269847Speter BuildMI(*MBB, MII, MI->getDebugLoc(), 91269847Speter TII->get(Hexagon::CONST32_Int_Real), 92269847Speter HEXAGON_RESERVED_REG_1).addImm(Offset); 93269847Speter BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_rr), 94269847Speter HEXAGON_RESERVED_REG_1) 95269847Speter .addReg(FP).addReg(HEXAGON_RESERVED_REG_1); 96269847Speter BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd), 97269847Speter HEXAGON_RESERVED_REG_2).addReg(SrcReg); 98269847Speter BuildMI(*MBB, MII, MI->getDebugLoc(), 99269847Speter TII->get(Hexagon::STriw_indexed)) 100269847Speter .addReg(HEXAGON_RESERVED_REG_1) 101269847Speter .addImm(0).addReg(HEXAGON_RESERVED_REG_2); 102269847Speter } else { 103269847Speter BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_ri), 104269847Speter HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset); 105269847Speter BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd), 106269847Speter HEXAGON_RESERVED_REG_2).addReg(SrcReg); 107269847Speter BuildMI(*MBB, MII, MI->getDebugLoc(), 108269847Speter TII->get(Hexagon::STriw_indexed)) 109269847Speter .addReg(HEXAGON_RESERVED_REG_1) 110269847Speter .addImm(0) 111269847Speter .addReg(HEXAGON_RESERVED_REG_2); 112269847Speter } 113269847Speter } else { 114269847Speter BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd), 115269847Speter HEXAGON_RESERVED_REG_2).addReg(SrcReg); 116269847Speter BuildMI(*MBB, MII, MI->getDebugLoc(), 117269847Speter TII->get(Hexagon::STriw_indexed)). 118269847Speter addReg(FP).addImm(Offset).addReg(HEXAGON_RESERVED_REG_2); 119269847Speter } 120269847Speter MII = MBB->erase(MI); 121251875Speter --MII; 122251875Speter } else if (Opc == Hexagon::LDriw_pred) { 123251875Speter // DstReg = LDriw_pred [R30], ofst. 124251875Speter int DstReg = MI->getOperand(0).getReg(); 125251875Speter assert(Hexagon::PredRegsRegClass.contains(DstReg) && 126251875Speter "Not a predicate register"); 127251875Speter unsigned FP = MI->getOperand(1).getReg(); 128251875Speter assert(FP == QTM.getRegisterInfo()->getFrameRegister() && 129251875Speter "Not a Frame Pointer, Nor a Spill Slot"); 130269847Speter assert(MI->getOperand(2).isImm() && "Not an offset"); 131251875Speter int Offset = MI->getOperand(2).getImm(); 132251875Speter if (!TII->isValidOffset(Hexagon::LDriw, Offset)) { 133251875Speter if (!TII->isValidOffset(Hexagon::ADD_ri, Offset)) { 134251875Speter BuildMI(*MBB, MII, MI->getDebugLoc(), 135251875Speter TII->get(Hexagon::CONST32_Int_Real), 136251875Speter HEXAGON_RESERVED_REG_1).addImm(Offset); 137251875Speter BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_rr), 138251875Speter HEXAGON_RESERVED_REG_1) 139251875Speter .addReg(FP) 140251875Speter .addReg(HEXAGON_RESERVED_REG_1); 141251875Speter BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::LDriw), 142251875Speter HEXAGON_RESERVED_REG_2) 143251875Speter .addReg(HEXAGON_RESERVED_REG_1) 144251875Speter .addImm(0); 145251875Speter BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_PdRs), 146251875Speter DstReg).addReg(HEXAGON_RESERVED_REG_2); 147251875Speter } else { 148251875Speter BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_ri), 149251875Speter HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset); 150251875Speter BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::LDriw), 151251875Speter HEXAGON_RESERVED_REG_2) 152251875Speter .addReg(HEXAGON_RESERVED_REG_1) 153251875Speter .addImm(0); 154251875Speter BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_PdRs), 155251875Speter DstReg).addReg(HEXAGON_RESERVED_REG_2); 156251875Speter } 157251875Speter } else { 158269847Speter BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::LDriw), 159269847Speter HEXAGON_RESERVED_REG_2).addReg(FP).addImm(Offset); 160269847Speter BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_PdRs), 161269847Speter DstReg).addReg(HEXAGON_RESERVED_REG_2); 162269847Speter } 163269847Speter MII = MBB->erase(MI); 164269847Speter --MII; 165269847Speter } 166269847Speter } 167269847Speter } 168269847Speter 169269847Speter return true; 170269847Speter} 171269847Speter 172269847Speter} 173251875Speter 174251875Speter//===----------------------------------------------------------------------===// 175251875Speter// Public Constructor Functions 176251875Speter//===----------------------------------------------------------------------===// 177251875Speter 178251875SpeterFunctionPass *llvm::createHexagonExpandPredSpillCode(HexagonTargetMachine &TM) { 179251875Speter return new HexagonExpandPredSpillCode(TM); 180251875Speter} 181251875Speter