003 File Manager
Current Path:
/usr/src/contrib/llvm-project/llvm/lib/Target/Hexagon
usr
/
src
/
contrib
/
llvm-project
/
llvm
/
lib
/
Target
/
Hexagon
/
📁
..
📁
AsmParser
📄
BitTracker.cpp
(35.36 KB)
📄
BitTracker.h
(17.25 KB)
📁
Disassembler
📄
Hexagon.h
(1004 B)
📄
Hexagon.td
(17.33 KB)
📄
HexagonArch.h
(1.2 KB)
📄
HexagonAsmPrinter.cpp
(26.65 KB)
📄
HexagonAsmPrinter.h
(2.03 KB)
📄
HexagonBitSimplify.cpp
(107.45 KB)
📄
HexagonBitTracker.cpp
(39.88 KB)
📄
HexagonBitTracker.h
(2.5 KB)
📄
HexagonBlockRanges.cpp
(15.85 KB)
📄
HexagonBlockRanges.h
(6.97 KB)
📄
HexagonBranchRelaxation.cpp
(7.78 KB)
📄
HexagonCFGOptimizer.cpp
(8.4 KB)
📄
HexagonCallingConv.td
(4.46 KB)
📄
HexagonCommonGEP.cpp
(41.47 KB)
📄
HexagonConstExtenders.cpp
(70.64 KB)
📄
HexagonConstPropagation.cpp
(97.75 KB)
📄
HexagonCopyToCombine.cpp
(32.2 KB)
📄
HexagonDepArch.h
(2.04 KB)
📄
HexagonDepArch.td
(1.87 KB)
📄
HexagonDepDecoders.inc
(2.55 KB)
📄
HexagonDepIICHVX.td
(113.05 KB)
📄
HexagonDepIICScalar.td
(224.12 KB)
📄
HexagonDepITypes.h
(1.51 KB)
📄
HexagonDepITypes.td
(1.91 KB)
📄
HexagonDepInstrFormats.td
(91.89 KB)
📄
HexagonDepInstrInfo.td
(1021.44 KB)
📄
HexagonDepMapAsm2Intrin.td
(255.17 KB)
📄
HexagonDepMappings.td
(64.27 KB)
📄
HexagonDepMask.h
(51.94 KB)
📄
HexagonDepOperands.td
(12.12 KB)
📄
HexagonDepTimingClasses.h
(4.69 KB)
📄
HexagonEarlyIfConv.cpp
(37.36 KB)
📄
HexagonExpandCondsets.cpp
(48.55 KB)
📄
HexagonFixupHwLoops.cpp
(6.54 KB)
📄
HexagonFrameLowering.cpp
(97.16 KB)
📄
HexagonFrameLowering.h
(7.85 KB)
📄
HexagonGenExtract.cpp
(8.61 KB)
📄
HexagonGenInsert.cpp
(53.24 KB)
📄
HexagonGenMux.cpp
(12.71 KB)
📄
HexagonGenPredicate.cpp
(16.25 KB)
📄
HexagonHardwareLoops.cpp
(70.32 KB)
📄
HexagonHazardRecognizer.cpp
(5.85 KB)
📄
HexagonHazardRecognizer.h
(3.58 KB)
📄
HexagonIICHVX.td
(1.21 KB)
📄
HexagonIICScalar.td
(1.34 KB)
📄
HexagonISelDAGToDAG.cpp
(78.63 KB)
📄
HexagonISelDAGToDAG.h
(5.88 KB)
📄
HexagonISelDAGToDAGHVX.cpp
(68.26 KB)
📄
HexagonISelLowering.cpp
(134.65 KB)
📄
HexagonISelLowering.h
(22.5 KB)
📄
HexagonISelLoweringHVX.cpp
(70.57 KB)
📄
HexagonInstrFormats.td
(12.04 KB)
📄
HexagonInstrFormatsV60.td
(1.03 KB)
📄
HexagonInstrFormatsV65.td
(1.54 KB)
📄
HexagonInstrInfo.cpp
(161.08 KB)
📄
HexagonInstrInfo.h
(25.31 KB)
📄
HexagonIntrinsics.td
(19.21 KB)
📄
HexagonIntrinsicsV5.td
(16.8 KB)
📄
HexagonIntrinsicsV60.td
(28.9 KB)
📄
HexagonLoopIdiomRecognition.cpp
(79.16 KB)
📄
HexagonMCInstLower.cpp
(6.25 KB)
📄
HexagonMachineFunctionInfo.cpp
(507 B)
📄
HexagonMachineFunctionInfo.h
(3.32 KB)
📄
HexagonMachineScheduler.cpp
(34.25 KB)
📄
HexagonMachineScheduler.h
(8.66 KB)
📄
HexagonMapAsm2IntrinV62.gen.td
(8.71 KB)
📄
HexagonMapAsm2IntrinV65.gen.td
(12.43 KB)
📄
HexagonNewValueJump.cpp
(25.57 KB)
📄
HexagonOperands.td
(1.62 KB)
📄
HexagonOptAddrMode.cpp
(29.37 KB)
📄
HexagonOptimizeSZextends.cpp
(4.74 KB)
📄
HexagonPatterns.td
(142.35 KB)
📄
HexagonPatternsHVX.td
(22.06 KB)
📄
HexagonPatternsV65.td
(2.96 KB)
📄
HexagonPeephole.cpp
(10.18 KB)
📄
HexagonPseudo.td
(21.62 KB)
📄
HexagonRDFOpt.cpp
(9.94 KB)
📄
HexagonRegisterInfo.cpp
(12.03 KB)
📄
HexagonRegisterInfo.h
(2.88 KB)
📄
HexagonRegisterInfo.td
(20.42 KB)
📄
HexagonSchedule.td
(2.33 KB)
📄
HexagonScheduleV5.td
(1.73 KB)
📄
HexagonScheduleV55.td
(1.81 KB)
📄
HexagonScheduleV60.td
(4.31 KB)
📄
HexagonScheduleV62.td
(1.53 KB)
📄
HexagonScheduleV65.td
(1.57 KB)
📄
HexagonScheduleV66.td
(1.57 KB)
📄
HexagonScheduleV67.td
(1.57 KB)
📄
HexagonScheduleV67T.td
(2.51 KB)
📄
HexagonSelectionDAGInfo.cpp
(2.35 KB)
📄
HexagonSelectionDAGInfo.h
(1.24 KB)
📄
HexagonSplitConst32AndConst64.cpp
(4.15 KB)
📄
HexagonSplitDouble.cpp
(37.86 KB)
📄
HexagonStoreWidening.cpp
(20.47 KB)
📄
HexagonSubtarget.cpp
(20.97 KB)
📄
HexagonSubtarget.h
(10.59 KB)
📄
HexagonTargetMachine.cpp
(16 KB)
📄
HexagonTargetMachine.h
(1.77 KB)
📄
HexagonTargetObjectFile.cpp
(16.8 KB)
📄
HexagonTargetObjectFile.h
(2.17 KB)
📄
HexagonTargetStreamer.h
(1.2 KB)
📄
HexagonTargetTransformInfo.cpp
(13.11 KB)
📄
HexagonTargetTransformInfo.h
(6.27 KB)
📄
HexagonVExtract.cpp
(6.64 KB)
📄
HexagonVLIWPacketizer.cpp
(67.01 KB)
📄
HexagonVLIWPacketizer.h
(6.09 KB)
📄
HexagonVectorLoopCarriedReuse.cpp
(23.99 KB)
📄
HexagonVectorPrint.cpp
(7.06 KB)
📁
MCTargetDesc
📄
RDFCopy.cpp
(6.37 KB)
📄
RDFCopy.h
(1.69 KB)
📄
RDFDeadCode.cpp
(7.5 KB)
📄
RDFDeadCode.h
(2.33 KB)
📁
TargetInfo
Editing: HexagonRegisterInfo.cpp
//===-- HexagonRegisterInfo.cpp - Hexagon Register Information ------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file contains the Hexagon implementation of the TargetRegisterInfo // class. // //===----------------------------------------------------------------------===// #include "HexagonRegisterInfo.h" #include "Hexagon.h" #include "HexagonMachineFunctionInfo.h" #include "HexagonSubtarget.h" #include "HexagonTargetMachine.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/CodeGen/LiveIntervals.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/IR/Function.h" #include "llvm/IR/Type.h" #include "llvm/MC/MachineLocation.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" #define GET_REGINFO_TARGET_DESC #include "HexagonGenRegisterInfo.inc" using namespace llvm; HexagonRegisterInfo::HexagonRegisterInfo(unsigned HwMode) : HexagonGenRegisterInfo(Hexagon::R31, 0/*DwarfFlavor*/, 0/*EHFlavor*/, 0/*PC*/, HwMode) {} 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 MCPhysReg * HexagonRegisterInfo::getCallerSavedRegs(const MachineFunction *MF, const TargetRegisterClass *RC) const { using namespace Hexagon; static const MCPhysReg Int32[] = { R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, 0 }; static const MCPhysReg Int64[] = { D0, D1, D2, D3, D4, D5, D6, D7, 0 }; static const MCPhysReg Pred[] = { P0, P1, P2, P3, 0 }; static const MCPhysReg VecSgl[] = { V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30, V31, 0 }; static const MCPhysReg VecDbl[] = { W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14, W15, 0 }; static const MCPhysReg VecPred[] = { Q0, Q1, Q2, Q3, 0 }; switch (RC->getID()) { case IntRegsRegClassID: return Int32; case DoubleRegsRegClassID: return Int64; case PredRegsRegClassID: return Pred; case HvxVRRegClassID: return VecSgl; case HvxWRRegClassID: return VecDbl; case HvxQRRegClassID: return VecPred; default: break; } static const MCPhysReg Empty[] = { 0 }; #ifndef NDEBUG dbgs() << "Register class: " << getRegClassName(RC) << "\n"; #endif llvm_unreachable("Unexpected register class"); return Empty; } 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 }; // Functions that contain a call to __builtin_eh_return also save the first 4 // parameter registers. static const MCPhysReg CalleeSavedRegsV3EHReturn[] = { Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, 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 }; bool HasEHReturn = MF->getInfo<HexagonMachineFunctionInfo>()->hasEHReturn(); return HasEHReturn ? CalleeSavedRegsV3EHReturn : CalleeSavedRegsV3; } const uint32_t *HexagonRegisterInfo::getCallPreservedMask( const MachineFunction &MF, CallingConv::ID) const { return HexagonCSR_RegMask; } BitVector HexagonRegisterInfo::getReservedRegs(const MachineFunction &MF) const { BitVector Reserved(getNumRegs()); Reserved.set(Hexagon::R29); Reserved.set(Hexagon::R30); Reserved.set(Hexagon::R31); Reserved.set(Hexagon::VTMP); // Guest registers. Reserved.set(Hexagon::GELR); // G0 Reserved.set(Hexagon::GSR); // G1 Reserved.set(Hexagon::GOSP); // G2 Reserved.set(Hexagon::G3); // G3 // Control registers. Reserved.set(Hexagon::SA0); // C0 Reserved.set(Hexagon::LC0); // C1 Reserved.set(Hexagon::SA1); // C2 Reserved.set(Hexagon::LC1); // C3 Reserved.set(Hexagon::P3_0); // C4 Reserved.set(Hexagon::USR); // C8 Reserved.set(Hexagon::PC); // C9 Reserved.set(Hexagon::UGP); // C10 Reserved.set(Hexagon::GP); // C11 Reserved.set(Hexagon::CS0); // C12 Reserved.set(Hexagon::CS1); // C13 Reserved.set(Hexagon::UPCYCLELO); // C14 Reserved.set(Hexagon::UPCYCLEHI); // C15 Reserved.set(Hexagon::FRAMELIMIT); // C16 Reserved.set(Hexagon::FRAMEKEY); // C17 Reserved.set(Hexagon::PKTCOUNTLO); // C18 Reserved.set(Hexagon::PKTCOUNTHI); // C19 Reserved.set(Hexagon::UTIMERLO); // C30 Reserved.set(Hexagon::UTIMERHI); // C31 // Out of the control registers, only C8 is explicitly defined in // HexagonRegisterInfo.td. If others are defined, make sure to add // them here as well. Reserved.set(Hexagon::C8); Reserved.set(Hexagon::USR_OVF); // Leveraging these registers will require more work to recognize // the new semantics posed, Hi/LoVec patterns, etc. // Note well: if enabled, they should be restricted to only // where `HST.useHVXOps() && HST.hasV67Ops()` is true. for (auto Reg : Hexagon_MC::GetVectRegRev()) Reserved.set(Reg); if (MF.getSubtarget<HexagonSubtarget>().hasReservedR19()) Reserved.set(Hexagon::R19); for (int x = Reserved.find_first(); x >= 0; x = Reserved.find_next(x)) markSuperRegs(Reserved, x); return Reserved; } void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOp, RegScavenger *RS) const { // // Hexagon_TODO: Do we need to enforce this for Hexagon? assert(SPAdj == 0 && "Unexpected"); MachineInstr &MI = *II; MachineBasicBlock &MB = *MI.getParent(); MachineFunction &MF = *MB.getParent(); auto &HST = MF.getSubtarget<HexagonSubtarget>(); auto &HII = *HST.getInstrInfo(); auto &HFI = *HST.getFrameLowering(); Register BP; int FI = MI.getOperand(FIOp).getIndex(); // Select the base pointer (BP) and calculate the actual offset from BP // to the beginning of the object at index FI. int Offset = HFI.getFrameIndexReference(MF, FI, BP); // Add the offset from the instruction. int RealOffset = Offset + MI.getOperand(FIOp+1).getImm(); bool IsKill = false; unsigned Opc = MI.getOpcode(); switch (Opc) { case Hexagon::PS_fia: MI.setDesc(HII.get(Hexagon::A2_addi)); MI.getOperand(FIOp).ChangeToImmediate(RealOffset); MI.RemoveOperand(FIOp+1); return; case Hexagon::PS_fi: // Set up the instruction for updating below. MI.setDesc(HII.get(Hexagon::A2_addi)); break; } if (!HII.isValidOffset(Opc, RealOffset, this)) { // If the offset is not valid, calculate the address in a temporary // register and use it with offset 0. auto &MRI = MF.getRegInfo(); Register TmpR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass); const DebugLoc &DL = MI.getDebugLoc(); BuildMI(MB, II, DL, HII.get(Hexagon::A2_addi), TmpR) .addReg(BP) .addImm(RealOffset); BP = TmpR; RealOffset = 0; IsKill = true; } MI.getOperand(FIOp).ChangeToRegister(BP, false, false, IsKill); MI.getOperand(FIOp+1).ChangeToImmediate(RealOffset); } bool HexagonRegisterInfo::shouldCoalesce(MachineInstr *MI, const TargetRegisterClass *SrcRC, unsigned SubReg, const TargetRegisterClass *DstRC, unsigned DstSubReg, const TargetRegisterClass *NewRC, LiveIntervals &LIS) const { // Coalescing will extend the live interval of the destination register. // If the destination register is a vector pair, avoid introducing function // calls into the interval, since it could result in a spilling of a pair // instead of a single vector. MachineFunction &MF = *MI->getParent()->getParent(); const HexagonSubtarget &HST = MF.getSubtarget<HexagonSubtarget>(); if (!HST.useHVXOps() || NewRC->getID() != Hexagon::HvxWRRegClass.getID()) return true; bool SmallSrc = SrcRC->getID() == Hexagon::HvxVRRegClass.getID(); bool SmallDst = DstRC->getID() == Hexagon::HvxVRRegClass.getID(); if (!SmallSrc && !SmallDst) return true; Register DstReg = MI->getOperand(0).getReg(); Register SrcReg = MI->getOperand(1).getReg(); const SlotIndexes &Indexes = *LIS.getSlotIndexes(); auto HasCall = [&Indexes] (const LiveInterval::Segment &S) { for (SlotIndex I = S.start.getBaseIndex(), E = S.end.getBaseIndex(); I != E; I = I.getNextIndex()) { if (const MachineInstr *MI = Indexes.getInstructionFromIndex(I)) if (MI->isCall()) return true; } return false; }; if (SmallSrc == SmallDst) { // Both must be true, because the case for both being false was // checked earlier. Both registers will be coalesced into a register // of a wider class (HvxWR), and we don't want its live range to // span over calls. return !any_of(LIS.getInterval(DstReg), HasCall) && !any_of(LIS.getInterval(SrcReg), HasCall); } // If one register is large (HvxWR) and the other is small (HvxVR), then // coalescing is ok if the large is already live across a function call, // or if the small one is not. unsigned SmallReg = SmallSrc ? SrcReg : DstReg; unsigned LargeReg = SmallSrc ? DstReg : SrcReg; return any_of(LIS.getInterval(LargeReg), HasCall) || !any_of(LIS.getInterval(SmallReg), HasCall); } unsigned HexagonRegisterInfo::getRARegister() const { return Hexagon::R31; } Register HexagonRegisterInfo::getFrameRegister(const MachineFunction &MF) const { const HexagonFrameLowering *TFI = getFrameLowering(MF); if (TFI->hasFP(MF)) return getFrameRegister(); return getStackRegister(); } unsigned HexagonRegisterInfo::getFrameRegister() const { return Hexagon::R30; } unsigned HexagonRegisterInfo::getStackRegister() const { return Hexagon::R29; } unsigned HexagonRegisterInfo::getHexagonSubRegIndex( const TargetRegisterClass &RC, unsigned GenIdx) const { assert(GenIdx == Hexagon::ps_sub_lo || GenIdx == Hexagon::ps_sub_hi); static const unsigned ISub[] = { Hexagon::isub_lo, Hexagon::isub_hi }; static const unsigned VSub[] = { Hexagon::vsub_lo, Hexagon::vsub_hi }; static const unsigned WSub[] = { Hexagon::wsub_lo, Hexagon::wsub_hi }; switch (RC.getID()) { case Hexagon::CtrRegs64RegClassID: case Hexagon::DoubleRegsRegClassID: return ISub[GenIdx]; case Hexagon::HvxWRRegClassID: return VSub[GenIdx]; case Hexagon::HvxVQRRegClassID: return WSub[GenIdx]; } if (const TargetRegisterClass *SuperRC = *RC.getSuperClasses()) return getHexagonSubRegIndex(*SuperRC, GenIdx); llvm_unreachable("Invalid register class"); } bool HexagonRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const { return MF.getSubtarget<HexagonSubtarget>().getFrameLowering()->hasFP(MF); } const TargetRegisterClass * HexagonRegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind) const { return &Hexagon::IntRegsRegClass; } unsigned HexagonRegisterInfo::getFirstCallerSavedNonParamReg() const { return Hexagon::R6; }
Upload File
Create Folder