X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FHexagon%2FHexagonRegisterInfo.cpp;h=8f255a08f5341522fbc46c43b6841dc1bf818b66;hb=0b48c1e633a249b150f059b18cc478f6307a01f7;hp=2a9de92329158baf6bad38beb45dc3b28ffd14b5;hpb=37097623bbde5420f81ab8d1d056700f8f258025;p=oota-llvm.git diff --git a/lib/Target/Hexagon/HexagonRegisterInfo.cpp b/lib/Target/Hexagon/HexagonRegisterInfo.cpp index 2a9de923291..8f255a08f53 100644 --- a/lib/Target/Hexagon/HexagonRegisterInfo.cpp +++ b/lib/Target/Hexagon/HexagonRegisterInfo.cpp @@ -14,55 +14,76 @@ #include "HexagonRegisterInfo.h" #include "Hexagon.h" +#include "HexagonMachineFunctionInfo.h" #include "HexagonSubtarget.h" #include "HexagonTargetMachine.h" -#include "HexagonMachineFunctionInfo.h" -#include "llvm/Function.h" -#include "llvm/Type.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/CodeGen/RegisterScavenging.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Type.h" #include "llvm/MC/MachineLocation.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/ErrorHandling.h" using namespace llvm; +HexagonRegisterInfo::HexagonRegisterInfo() + : HexagonGenRegisterInfo(Hexagon::R31) {} + -HexagonRegisterInfo::HexagonRegisterInfo(HexagonSubtarget &st, - const HexagonInstrInfo &tii) - : HexagonGenRegisterInfo(Hexagon::R31), - Subtarget(st), - TII(tii) { +bool HexagonRegisterInfo::isEHReturnCalleeSaveReg(unsigned R) const { + return R == Hexagon::R0 || R == Hexagon::R1 || R == Hexagon::R2 || + R == Hexagon::R3 || R == Hexagon::D0 || R == Hexagon::D1; } -const uint16_t* HexagonRegisterInfo::getCalleeSavedRegs(const MachineFunction - *MF) - const { - static const uint16_t CalleeSavedRegsV2[] = { - Hexagon::R24, Hexagon::R25, Hexagon::R26, Hexagon::R27, 0 +bool HexagonRegisterInfo::isCalleeSaveReg(unsigned Reg) const { + return Hexagon::R16 <= Reg && Reg <= Hexagon::R27; +} + + +const MCPhysReg * +HexagonRegisterInfo::getCallerSavedRegs(const MachineFunction *MF) const { + static const MCPhysReg CallerSavedRegsV4[] = { + Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4, + Hexagon::R5, Hexagon::R6, Hexagon::R7, Hexagon::R8, Hexagon::R9, + Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14, + Hexagon::R15, 0 }; - static const uint16_t CalleeSavedRegsV3[] = { + + auto &HST = static_cast(MF->getSubtarget()); + switch (HST.getHexagonArchVersion()) { + case HexagonSubtarget::V4: + case HexagonSubtarget::V5: + return CallerSavedRegsV4; + } + llvm_unreachable( + "Callee saved registers requested for unknown archtecture version"); +} + + +const MCPhysReg * +HexagonRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { + static const MCPhysReg CalleeSavedRegsV3[] = { Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19, Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, Hexagon::R24, Hexagon::R25, Hexagon::R26, Hexagon::R27, 0 }; - switch(Subtarget.getHexagonArchVersion()) { - case HexagonSubtarget::V1: - break; - case HexagonSubtarget::V2: - return CalleeSavedRegsV2; - case HexagonSubtarget::V3: + switch (MF->getSubtarget().getHexagonArchVersion()) { case HexagonSubtarget::V4: + case HexagonSubtarget::V5: return CalleeSavedRegsV3; } llvm_unreachable("Callee saved registers requested for unknown architecture " @@ -87,229 +108,153 @@ BitVector HexagonRegisterInfo::getReservedRegs(const MachineFunction &MF) } -const TargetRegisterClass* const* -HexagonRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { - static const TargetRegisterClass * const CalleeSavedRegClassesV2[] = { - &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, - &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, - }; - static const TargetRegisterClass * const CalleeSavedRegClassesV3[] = { - &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, - &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, - &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, - &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, - &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, - &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, - }; - - switch(Subtarget.getHexagonArchVersion()) { - case HexagonSubtarget::V1: - break; - case HexagonSubtarget::V2: - return CalleeSavedRegClassesV2; - case HexagonSubtarget::V3: - case HexagonSubtarget::V4: - return CalleeSavedRegClassesV3; - } - llvm_unreachable("Callee saved register classes requested for unknown " - "architecture version"); -} - -void HexagonRegisterInfo:: -eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, - MachineBasicBlock::iterator I) const { - MachineInstr &MI = *I; - - if (MI.getOpcode() == Hexagon::ADJCALLSTACKDOWN) { - // Hexagon_TODO: add code - } else if (MI.getOpcode() == Hexagon::ADJCALLSTACKUP) { - // Hexagon_TODO: add code - } else { - llvm_unreachable("Cannot handle this call frame pseudo instruction"); - } - MBB.erase(I); -} - void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, - int SPAdj, RegScavenger *RS) const { - + int SPAdj, unsigned FIOp, + RegScavenger *RS) const { // // Hexagon_TODO: Do we need to enforce this for Hexagon? assert(SPAdj == 0 && "Unexpected"); - - unsigned i = 0; MachineInstr &MI = *II; - while (!MI.getOperand(i).isFI()) { - ++i; - assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); - } - - int FrameIndex = MI.getOperand(i).getIndex(); - // Addressable stack objects are accessed using neg. offsets from %fp. - MachineFunction &MF = *MI.getParent()->getParent(); - int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex); + MachineBasicBlock &MB = *MI.getParent(); + MachineFunction &MF = *MB.getParent(); MachineFrameInfo &MFI = *MF.getFrameInfo(); - - unsigned FrameReg = getFrameRegister(MF); - const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); - if (!TFI->hasFP(MF)) { + auto &HST = static_cast(MF.getSubtarget()); + auto &HII = *HST.getInstrInfo(); + auto &HFI = *HST.getFrameLowering(); + + int FI = MI.getOperand(FIOp).getIndex(); + int Offset = MFI.getObjectOffset(FI) + MI.getOperand(FIOp+1).getImm(); + bool HasAlloca = MFI.hasVarSizedObjects(); + bool HasAlign = needsStackRealignment(MF); + + // XXX: Fixed objects cannot be accessed through SP if there are aligned + // objects in the local frame, or if there are dynamically allocated objects. + // In such cases, there has to be FP available. + if (!HFI.hasFP(MF)) { + assert(!HasAlloca && !HasAlign && "This function must have frame pointer"); // We will not reserve space on the stack for the lr and fp registers. - Offset -= 2 * Hexagon_WordSize; + Offset -= 8; } - const unsigned FrameSize = MFI.getStackSize(); + unsigned SP = getStackRegister(), FP = getFrameRegister(); + unsigned AP = 0; + if (MachineInstr *AI = HFI.getAlignaInstr(MF)) + AP = AI->getOperand(0).getReg(); + unsigned FrameSize = MFI.getStackSize(); + + // Special handling of dbg_value instructions and INLINEASM. + if (MI.isDebugValue() || MI.isInlineAsm()) { + MI.getOperand(FIOp).ChangeToRegister(SP, false /*isDef*/); + MI.getOperand(FIOp+1).ChangeToImmediate(Offset+FrameSize); + return; + } - if (!MFI.hasVarSizedObjects() && - TII.isValidOffset(MI.getOpcode(), (FrameSize+Offset)) && - !TII.isSpillPredRegOp(&MI)) { - // Replace frame index with a stack pointer reference. - MI.getOperand(i).ChangeToRegister(getStackRegister(), false, false, true); - MI.getOperand(i+1).ChangeToImmediate(FrameSize+Offset); + bool UseFP = false, UseAP = false; // Default: use SP. + if (MFI.isFixedObjectIndex(FI) || MFI.isObjectPreAllocated(FI)) { + UseFP = HasAlloca || HasAlign; } else { - // Replace frame index with a frame pointer reference. - if (!TII.isValidOffset(MI.getOpcode(), Offset)) { - - // If the offset overflows, then correct it. - // - // For loads, we do not need a reserved register - // r0 = memw(r30 + #10000) to: - // - // r0 = add(r30, #10000) - // r0 = memw(r0) - if ( (MI.getOpcode() == Hexagon::LDriw) || - (MI.getOpcode() == Hexagon::LDrid) || - (MI.getOpcode() == Hexagon::LDrih) || - (MI.getOpcode() == Hexagon::LDriuh) || - (MI.getOpcode() == Hexagon::LDrib) || - (MI.getOpcode() == Hexagon::LDriub) ) { - unsigned dstReg = (MI.getOpcode() == Hexagon::LDrid) ? - *getSubRegisters(MI.getOperand(0).getReg()) : - MI.getOperand(0).getReg(); - - // Check if offset can fit in addi. - if (!TII.isValidOffset(Hexagon::ADD_ri, Offset)) { - BuildMI(*MI.getParent(), II, MI.getDebugLoc(), - TII.get(Hexagon::CONST32_Int_Real), dstReg).addImm(Offset); - BuildMI(*MI.getParent(), II, MI.getDebugLoc(), - TII.get(Hexagon::ADD_rr), - dstReg).addReg(FrameReg).addReg(dstReg); - } else { - BuildMI(*MI.getParent(), II, MI.getDebugLoc(), - TII.get(Hexagon::ADD_ri), - dstReg).addReg(FrameReg).addImm(Offset); - } - - MI.getOperand(i).ChangeToRegister(dstReg, false, false, true); - MI.getOperand(i+1).ChangeToImmediate(0); - } else if ((MI.getOpcode() == Hexagon::STriw) || - (MI.getOpcode() == Hexagon::STrid) || - (MI.getOpcode() == Hexagon::STrih) || - (MI.getOpcode() == Hexagon::STrib)) { - // For stores, we need a reserved register. Change - // memw(r30 + #10000) = r0 to: - // - // rs = add(r30, #10000); - // memw(rs) = r0 - unsigned resReg = HEXAGON_RESERVED_REG_1; - - // Check if offset can fit in addi. - if (!TII.isValidOffset(Hexagon::ADD_ri, Offset)) { - BuildMI(*MI.getParent(), II, MI.getDebugLoc(), - TII.get(Hexagon::CONST32_Int_Real), resReg).addImm(Offset); - BuildMI(*MI.getParent(), II, MI.getDebugLoc(), - TII.get(Hexagon::ADD_rr), - resReg).addReg(FrameReg).addReg(resReg); - } else { - BuildMI(*MI.getParent(), II, MI.getDebugLoc(), - TII.get(Hexagon::ADD_ri), - resReg).addReg(FrameReg).addImm(Offset); - } - MI.getOperand(i).ChangeToRegister(resReg, false, false, true); - MI.getOperand(i+1).ChangeToImmediate(0); - } else if (TII.isMemOp(&MI)) { - unsigned resReg = HEXAGON_RESERVED_REG_1; - if (!MFI.hasVarSizedObjects() && - TII.isValidOffset(MI.getOpcode(), (FrameSize+Offset))) { - MI.getOperand(i).ChangeToRegister(getStackRegister(), false, false, - true); - MI.getOperand(i+1).ChangeToImmediate(FrameSize+Offset); - } else if (!TII.isValidOffset(Hexagon::ADD_ri, Offset)) { - BuildMI(*MI.getParent(), II, MI.getDebugLoc(), - TII.get(Hexagon::CONST32_Int_Real), resReg).addImm(Offset); - BuildMI(*MI.getParent(), II, MI.getDebugLoc(), - TII.get(Hexagon::ADD_rr), - resReg).addReg(FrameReg).addReg(resReg); - MI.getOperand(i).ChangeToRegister(resReg, false, false, true); - MI.getOperand(i+1).ChangeToImmediate(0); - } else { - BuildMI(*MI.getParent(), II, MI.getDebugLoc(), - TII.get(Hexagon::ADD_ri), - resReg).addReg(FrameReg).addImm(Offset); - MI.getOperand(i).ChangeToRegister(resReg, false, false, true); - MI.getOperand(i+1).ChangeToImmediate(0); - } - } else { - unsigned dstReg = MI.getOperand(0).getReg(); - BuildMI(*MI.getParent(), II, MI.getDebugLoc(), - TII.get(Hexagon::CONST32_Int_Real), dstReg).addImm(Offset); - BuildMI(*MI.getParent(), II, MI.getDebugLoc(), - TII.get(Hexagon::ADD_rr), - dstReg).addReg(FrameReg).addReg(dstReg); - // Can we delete MI??? r2 = add (r2, #0). - MI.getOperand(i).ChangeToRegister(dstReg, false, false, true); - MI.getOperand(i+1).ChangeToImmediate(0); - } - } else { - // If the offset is small enough to fit in the immediate field, directly - // encode it. - MI.getOperand(i).ChangeToRegister(FrameReg, false); - MI.getOperand(i+1).ChangeToImmediate(Offset); + if (HasAlloca) { + if (HasAlign) + UseAP = true; + else + UseFP = true; } } + unsigned Opc = MI.getOpcode(); + bool ValidSP = HII.isValidOffset(Opc, FrameSize+Offset); + bool ValidFP = HII.isValidOffset(Opc, Offset); + + // Calculate the actual offset in the instruction. + int64_t RealOffset = Offset; + if (!UseFP && !UseAP) + RealOffset = FrameSize+Offset; + + switch (Opc) { + case Hexagon::TFR_FIA: + MI.setDesc(HII.get(Hexagon::A2_addi)); + MI.getOperand(FIOp).ChangeToImmediate(RealOffset); + MI.RemoveOperand(FIOp+1); + return; + case Hexagon::TFR_FI: + // Set up the instruction for updating below. + MI.setDesc(HII.get(Hexagon::A2_addi)); + break; + } + + unsigned BP = 0; + bool Valid = false; + if (UseFP) { + BP = FP; + Valid = ValidFP; + } else if (UseAP) { + BP = AP; + Valid = ValidFP; + } else { + BP = SP; + Valid = ValidSP; + } + + if (Valid) { + MI.getOperand(FIOp).ChangeToRegister(BP, false); + MI.getOperand(FIOp+1).ChangeToImmediate(RealOffset); + return; + } + +#ifndef NDEBUG + const Function *F = MF.getFunction(); + dbgs() << "In function "; + if (F) dbgs() << F->getName(); + else dbgs() << ""; + dbgs() << ", BB#" << MB.getNumber() << "\n" << MI; +#endif + llvm_unreachable("Unhandled instruction"); } + unsigned HexagonRegisterInfo::getRARegister() const { return Hexagon::R31; } + unsigned HexagonRegisterInfo::getFrameRegister(const MachineFunction &MF) const { - const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); - if (TFI->hasFP(MF)) { + const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); + if (TFI->hasFP(MF)) return Hexagon::R30; - } - return Hexagon::R29; } + unsigned HexagonRegisterInfo::getFrameRegister() const { return Hexagon::R30; } + unsigned HexagonRegisterInfo::getStackRegister() const { return Hexagon::R29; } -void HexagonRegisterInfo::getInitialFrameState(std::vector - &Moves) const -{ - // VirtualFP = (R30 + #0). - unsigned FPReg = getFrameRegister(); - MachineLocation Dst(MachineLocation::VirtualFP); - MachineLocation Src(FPReg, 0); - Moves.push_back(MachineMove(0, Dst, Src)); + +bool +HexagonRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const { + return MF.getSubtarget().getFrameLowering()->hasFP(MF); } -unsigned HexagonRegisterInfo::getEHExceptionRegister() const { - llvm_unreachable("What is the exception register"); + +bool +HexagonRegisterInfo::needsStackRealignment(const MachineFunction &MF) const { + const MachineFrameInfo *MFI = MF.getFrameInfo(); + return MFI->getMaxAlignment() > 8; } -unsigned HexagonRegisterInfo::getEHHandlerRegister() const { - llvm_unreachable("What is the exception handler register"); + +unsigned HexagonRegisterInfo::getFirstCallerSavedNonParamReg() const { + return Hexagon::R6; } + #define GET_REGINFO_TARGET_DESC #include "HexagonGenRegisterInfo.inc"