10b57cec5SDimitry Andric //===-- ARMBaseRegisterInfo.cpp - ARM Register Information ----------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file contains the base ARM implementation of TargetRegisterInfo class. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "ARMBaseRegisterInfo.h" 140b57cec5SDimitry Andric #include "ARM.h" 150b57cec5SDimitry Andric #include "ARMBaseInstrInfo.h" 160b57cec5SDimitry Andric #include "ARMFrameLowering.h" 170b57cec5SDimitry Andric #include "ARMMachineFunctionInfo.h" 180b57cec5SDimitry Andric #include "ARMSubtarget.h" 190b57cec5SDimitry Andric #include "MCTargetDesc/ARMAddressingModes.h" 200b57cec5SDimitry Andric #include "MCTargetDesc/ARMBaseInfo.h" 210b57cec5SDimitry Andric #include "llvm/ADT/BitVector.h" 220b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 230b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 240b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 250b57cec5SDimitry Andric #include "llvm/CodeGen/MachineConstantPool.h" 260b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 270b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 280b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 290b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 300b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h" 310b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 320b57cec5SDimitry Andric #include "llvm/CodeGen/RegisterScavenging.h" 330b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 340b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 350b57cec5SDimitry Andric #include "llvm/CodeGen/VirtRegMap.h" 360b57cec5SDimitry Andric #include "llvm/IR/Attributes.h" 370b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 380b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h" 390b57cec5SDimitry Andric #include "llvm/IR/Function.h" 400b57cec5SDimitry Andric #include "llvm/IR/Type.h" 410b57cec5SDimitry Andric #include "llvm/MC/MCInstrDesc.h" 420b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 430b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 440b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 450b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 460b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h" 470b57cec5SDimitry Andric #include <cassert> 480b57cec5SDimitry Andric #include <utility> 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric #define DEBUG_TYPE "arm-register-info" 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric #define GET_REGINFO_TARGET_DESC 530b57cec5SDimitry Andric #include "ARMGenRegisterInfo.inc" 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric using namespace llvm; 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric ARMBaseRegisterInfo::ARMBaseRegisterInfo() 58e8d8bef9SDimitry Andric : ARMGenRegisterInfo(ARM::LR, 0, 0, ARM::PC) { 59e8d8bef9SDimitry Andric ARM_MC::initLLVMToCVRegMapping(this); 60e8d8bef9SDimitry Andric } 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric const MCPhysReg* 630b57cec5SDimitry Andric ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 640b57cec5SDimitry Andric const ARMSubtarget &STI = MF->getSubtarget<ARMSubtarget>(); 650b57cec5SDimitry Andric bool UseSplitPush = STI.splitFramePushPop(*MF); 660b57cec5SDimitry Andric const MCPhysReg *RegList = 670b57cec5SDimitry Andric STI.isTargetDarwin() 680b57cec5SDimitry Andric ? CSR_iOS_SaveList 690b57cec5SDimitry Andric : (UseSplitPush ? CSR_AAPCS_SplitPush_SaveList : CSR_AAPCS_SaveList); 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric const Function &F = MF->getFunction(); 720b57cec5SDimitry Andric if (F.getCallingConv() == CallingConv::GHC) { 730b57cec5SDimitry Andric // GHC set of callee saved regs is empty as all those regs are 740b57cec5SDimitry Andric // used for passing STG regs around 750b57cec5SDimitry Andric return CSR_NoRegs_SaveList; 76480093f4SDimitry Andric } else if (F.getCallingConv() == CallingConv::CFGuard_Check) { 77480093f4SDimitry Andric return CSR_Win_AAPCS_CFGuard_Check_SaveList; 78fe6060f1SDimitry Andric } else if (F.getCallingConv() == CallingConv::SwiftTail) { 79fe6060f1SDimitry Andric return STI.isTargetDarwin() 80fe6060f1SDimitry Andric ? CSR_iOS_SwiftTail_SaveList 81fe6060f1SDimitry Andric : (UseSplitPush ? CSR_AAPCS_SplitPush_SwiftTail_SaveList 82fe6060f1SDimitry Andric : CSR_AAPCS_SwiftTail_SaveList); 830b57cec5SDimitry Andric } else if (F.hasFnAttribute("interrupt")) { 840b57cec5SDimitry Andric if (STI.isMClass()) { 850b57cec5SDimitry Andric // M-class CPUs have hardware which saves the registers needed to allow a 860b57cec5SDimitry Andric // function conforming to the AAPCS to function as a handler. 870b57cec5SDimitry Andric return UseSplitPush ? CSR_AAPCS_SplitPush_SaveList : CSR_AAPCS_SaveList; 880b57cec5SDimitry Andric } else if (F.getFnAttribute("interrupt").getValueAsString() == "FIQ") { 890b57cec5SDimitry Andric // Fast interrupt mode gives the handler a private copy of R8-R14, so less 900b57cec5SDimitry Andric // need to be saved to restore user-mode state. 910b57cec5SDimitry Andric return CSR_FIQ_SaveList; 920b57cec5SDimitry Andric } else { 930b57cec5SDimitry Andric // Generally only R13-R14 (i.e. SP, LR) are automatically preserved by 940b57cec5SDimitry Andric // exception handling. 950b57cec5SDimitry Andric return CSR_GenericInt_SaveList; 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric } 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric if (STI.getTargetLowering()->supportSwiftError() && 1000b57cec5SDimitry Andric F.getAttributes().hasAttrSomewhere(Attribute::SwiftError)) { 1010b57cec5SDimitry Andric if (STI.isTargetDarwin()) 1020b57cec5SDimitry Andric return CSR_iOS_SwiftError_SaveList; 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric return UseSplitPush ? CSR_AAPCS_SplitPush_SwiftError_SaveList : 1050b57cec5SDimitry Andric CSR_AAPCS_SwiftError_SaveList; 1060b57cec5SDimitry Andric } 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric if (STI.isTargetDarwin() && F.getCallingConv() == CallingConv::CXX_FAST_TLS) 1090b57cec5SDimitry Andric return MF->getInfo<ARMFunctionInfo>()->isSplitCSR() 1100b57cec5SDimitry Andric ? CSR_iOS_CXX_TLS_PE_SaveList 1110b57cec5SDimitry Andric : CSR_iOS_CXX_TLS_SaveList; 1120b57cec5SDimitry Andric return RegList; 1130b57cec5SDimitry Andric } 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andric const MCPhysReg *ARMBaseRegisterInfo::getCalleeSavedRegsViaCopy( 1160b57cec5SDimitry Andric const MachineFunction *MF) const { 1170b57cec5SDimitry Andric assert(MF && "Invalid MachineFunction pointer."); 1180b57cec5SDimitry Andric if (MF->getFunction().getCallingConv() == CallingConv::CXX_FAST_TLS && 1190b57cec5SDimitry Andric MF->getInfo<ARMFunctionInfo>()->isSplitCSR()) 1200b57cec5SDimitry Andric return CSR_iOS_CXX_TLS_ViaCopy_SaveList; 1210b57cec5SDimitry Andric return nullptr; 1220b57cec5SDimitry Andric } 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric const uint32_t * 1250b57cec5SDimitry Andric ARMBaseRegisterInfo::getCallPreservedMask(const MachineFunction &MF, 1260b57cec5SDimitry Andric CallingConv::ID CC) const { 1270b57cec5SDimitry Andric const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); 1280b57cec5SDimitry Andric if (CC == CallingConv::GHC) 1290b57cec5SDimitry Andric // This is academic because all GHC calls are (supposed to be) tail calls 1300b57cec5SDimitry Andric return CSR_NoRegs_RegMask; 131480093f4SDimitry Andric if (CC == CallingConv::CFGuard_Check) 132480093f4SDimitry Andric return CSR_Win_AAPCS_CFGuard_Check_RegMask; 133fe6060f1SDimitry Andric if (CC == CallingConv::SwiftTail) { 134fe6060f1SDimitry Andric return STI.isTargetDarwin() ? CSR_iOS_SwiftTail_RegMask 135fe6060f1SDimitry Andric : CSR_AAPCS_SwiftTail_RegMask; 136fe6060f1SDimitry Andric } 1370b57cec5SDimitry Andric if (STI.getTargetLowering()->supportSwiftError() && 1380b57cec5SDimitry Andric MF.getFunction().getAttributes().hasAttrSomewhere(Attribute::SwiftError)) 1390b57cec5SDimitry Andric return STI.isTargetDarwin() ? CSR_iOS_SwiftError_RegMask 1400b57cec5SDimitry Andric : CSR_AAPCS_SwiftError_RegMask; 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric if (STI.isTargetDarwin() && CC == CallingConv::CXX_FAST_TLS) 1430b57cec5SDimitry Andric return CSR_iOS_CXX_TLS_RegMask; 1440b57cec5SDimitry Andric return STI.isTargetDarwin() ? CSR_iOS_RegMask : CSR_AAPCS_RegMask; 1450b57cec5SDimitry Andric } 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric const uint32_t* 1480b57cec5SDimitry Andric ARMBaseRegisterInfo::getNoPreservedMask() const { 1490b57cec5SDimitry Andric return CSR_NoRegs_RegMask; 1500b57cec5SDimitry Andric } 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric const uint32_t * 1530b57cec5SDimitry Andric ARMBaseRegisterInfo::getTLSCallPreservedMask(const MachineFunction &MF) const { 1540b57cec5SDimitry Andric assert(MF.getSubtarget<ARMSubtarget>().isTargetDarwin() && 1550b57cec5SDimitry Andric "only know about special TLS call on Darwin"); 1560b57cec5SDimitry Andric return CSR_iOS_TLSCall_RegMask; 1570b57cec5SDimitry Andric } 1580b57cec5SDimitry Andric 1590b57cec5SDimitry Andric const uint32_t * 1600b57cec5SDimitry Andric ARMBaseRegisterInfo::getSjLjDispatchPreservedMask(const MachineFunction &MF) const { 1610b57cec5SDimitry Andric const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); 1620b57cec5SDimitry Andric if (!STI.useSoftFloat() && STI.hasVFP2Base() && !STI.isThumb1Only()) 1630b57cec5SDimitry Andric return CSR_NoRegs_RegMask; 1640b57cec5SDimitry Andric else 1650b57cec5SDimitry Andric return CSR_FPRegs_RegMask; 1660b57cec5SDimitry Andric } 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric const uint32_t * 1690b57cec5SDimitry Andric ARMBaseRegisterInfo::getThisReturnPreservedMask(const MachineFunction &MF, 1700b57cec5SDimitry Andric CallingConv::ID CC) const { 1710b57cec5SDimitry Andric const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); 1720b57cec5SDimitry Andric // This should return a register mask that is the same as that returned by 1730b57cec5SDimitry Andric // getCallPreservedMask but that additionally preserves the register used for 1740b57cec5SDimitry Andric // the first i32 argument (which must also be the register used to return a 1750b57cec5SDimitry Andric // single i32 return value) 1760b57cec5SDimitry Andric // 1770b57cec5SDimitry Andric // In case that the calling convention does not use the same register for 1780b57cec5SDimitry Andric // both or otherwise does not want to enable this optimization, the function 1790b57cec5SDimitry Andric // should return NULL 1800b57cec5SDimitry Andric if (CC == CallingConv::GHC) 1810b57cec5SDimitry Andric // This is academic because all GHC calls are (supposed to be) tail calls 1820b57cec5SDimitry Andric return nullptr; 1830b57cec5SDimitry Andric return STI.isTargetDarwin() ? CSR_iOS_ThisReturn_RegMask 1840b57cec5SDimitry Andric : CSR_AAPCS_ThisReturn_RegMask; 1850b57cec5SDimitry Andric } 1860b57cec5SDimitry Andric 1878bcb0991SDimitry Andric ArrayRef<MCPhysReg> ARMBaseRegisterInfo::getIntraCallClobberedRegs( 1888bcb0991SDimitry Andric const MachineFunction *MF) const { 1898bcb0991SDimitry Andric static const MCPhysReg IntraCallClobberedRegs[] = {ARM::R12}; 1908bcb0991SDimitry Andric return ArrayRef<MCPhysReg>(IntraCallClobberedRegs); 1918bcb0991SDimitry Andric } 1928bcb0991SDimitry Andric 1930b57cec5SDimitry Andric BitVector ARMBaseRegisterInfo:: 1940b57cec5SDimitry Andric getReservedRegs(const MachineFunction &MF) const { 1950b57cec5SDimitry Andric const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); 1960b57cec5SDimitry Andric const ARMFrameLowering *TFI = getFrameLowering(MF); 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric // FIXME: avoid re-calculating this every time. 1990b57cec5SDimitry Andric BitVector Reserved(getNumRegs()); 2000b57cec5SDimitry Andric markSuperRegs(Reserved, ARM::SP); 2010b57cec5SDimitry Andric markSuperRegs(Reserved, ARM::PC); 2020b57cec5SDimitry Andric markSuperRegs(Reserved, ARM::FPSCR); 2030b57cec5SDimitry Andric markSuperRegs(Reserved, ARM::APSR_NZCV); 204480093f4SDimitry Andric if (TFI->hasFP(MF)) 205fe6060f1SDimitry Andric markSuperRegs(Reserved, STI.getFramePointerReg()); 2060b57cec5SDimitry Andric if (hasBasePointer(MF)) 2070b57cec5SDimitry Andric markSuperRegs(Reserved, BasePtr); 2080b57cec5SDimitry Andric // Some targets reserve R9. 2090b57cec5SDimitry Andric if (STI.isR9Reserved()) 2100b57cec5SDimitry Andric markSuperRegs(Reserved, ARM::R9); 2110b57cec5SDimitry Andric // Reserve D16-D31 if the subtarget doesn't support them. 2120b57cec5SDimitry Andric if (!STI.hasD32()) { 2130b57cec5SDimitry Andric static_assert(ARM::D31 == ARM::D16 + 15, "Register list not consecutive!"); 2140b57cec5SDimitry Andric for (unsigned R = 0; R < 16; ++R) 2150b57cec5SDimitry Andric markSuperRegs(Reserved, ARM::D16 + R); 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric const TargetRegisterClass &RC = ARM::GPRPairRegClass; 2180b57cec5SDimitry Andric for (unsigned Reg : RC) 2190b57cec5SDimitry Andric for (MCSubRegIterator SI(Reg, this); SI.isValid(); ++SI) 2200b57cec5SDimitry Andric if (Reserved.test(*SI)) 2210b57cec5SDimitry Andric markSuperRegs(Reserved, Reg); 2220b57cec5SDimitry Andric // For v8.1m architecture 2230b57cec5SDimitry Andric markSuperRegs(Reserved, ARM::ZR); 2240b57cec5SDimitry Andric 2250b57cec5SDimitry Andric assert(checkAllSuperRegsMarked(Reserved)); 2260b57cec5SDimitry Andric return Reserved; 2270b57cec5SDimitry Andric } 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric bool ARMBaseRegisterInfo:: 2305ffd83dbSDimitry Andric isAsmClobberable(const MachineFunction &MF, MCRegister PhysReg) const { 2310b57cec5SDimitry Andric return !getReservedRegs(MF).test(PhysReg); 2320b57cec5SDimitry Andric } 2330b57cec5SDimitry Andric 2345ffd83dbSDimitry Andric bool ARMBaseRegisterInfo::isInlineAsmReadOnlyReg(const MachineFunction &MF, 2355ffd83dbSDimitry Andric unsigned PhysReg) const { 2365ffd83dbSDimitry Andric const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); 2375ffd83dbSDimitry Andric const ARMFrameLowering *TFI = getFrameLowering(MF); 2385ffd83dbSDimitry Andric 2395ffd83dbSDimitry Andric BitVector Reserved(getNumRegs()); 2405ffd83dbSDimitry Andric markSuperRegs(Reserved, ARM::PC); 2415ffd83dbSDimitry Andric if (TFI->hasFP(MF)) 242fe6060f1SDimitry Andric markSuperRegs(Reserved, STI.getFramePointerReg()); 2435ffd83dbSDimitry Andric if (hasBasePointer(MF)) 2445ffd83dbSDimitry Andric markSuperRegs(Reserved, BasePtr); 2455ffd83dbSDimitry Andric assert(checkAllSuperRegsMarked(Reserved)); 2465ffd83dbSDimitry Andric return Reserved.test(PhysReg); 2475ffd83dbSDimitry Andric } 2485ffd83dbSDimitry Andric 2490b57cec5SDimitry Andric const TargetRegisterClass * 2500b57cec5SDimitry Andric ARMBaseRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC, 2518bcb0991SDimitry Andric const MachineFunction &MF) const { 2520b57cec5SDimitry Andric const TargetRegisterClass *Super = RC; 2530b57cec5SDimitry Andric TargetRegisterClass::sc_iterator I = RC->getSuperClasses(); 2540b57cec5SDimitry Andric do { 2550b57cec5SDimitry Andric switch (Super->getID()) { 2560b57cec5SDimitry Andric case ARM::GPRRegClassID: 2570b57cec5SDimitry Andric case ARM::SPRRegClassID: 2580b57cec5SDimitry Andric case ARM::DPRRegClassID: 2598bcb0991SDimitry Andric case ARM::GPRPairRegClassID: 2608bcb0991SDimitry Andric return Super; 2610b57cec5SDimitry Andric case ARM::QPRRegClassID: 2620b57cec5SDimitry Andric case ARM::QQPRRegClassID: 2630b57cec5SDimitry Andric case ARM::QQQQPRRegClassID: 2648bcb0991SDimitry Andric if (MF.getSubtarget<ARMSubtarget>().hasNEON()) 2650b57cec5SDimitry Andric return Super; 266349cc55cSDimitry Andric break; 267349cc55cSDimitry Andric case ARM::MQPRRegClassID: 268349cc55cSDimitry Andric case ARM::MQQPRRegClassID: 269349cc55cSDimitry Andric case ARM::MQQQQPRRegClassID: 270349cc55cSDimitry Andric if (MF.getSubtarget<ARMSubtarget>().hasMVEIntegerOps()) 271349cc55cSDimitry Andric return Super; 272349cc55cSDimitry Andric break; 2730b57cec5SDimitry Andric } 2740b57cec5SDimitry Andric Super = *I++; 2750b57cec5SDimitry Andric } while (Super); 2760b57cec5SDimitry Andric return RC; 2770b57cec5SDimitry Andric } 2780b57cec5SDimitry Andric 2790b57cec5SDimitry Andric const TargetRegisterClass * 2800b57cec5SDimitry Andric ARMBaseRegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind) 2810b57cec5SDimitry Andric const { 2820b57cec5SDimitry Andric return &ARM::GPRRegClass; 2830b57cec5SDimitry Andric } 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric const TargetRegisterClass * 2860b57cec5SDimitry Andric ARMBaseRegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const { 2870b57cec5SDimitry Andric if (RC == &ARM::CCRRegClass) 2880b57cec5SDimitry Andric return &ARM::rGPRRegClass; // Can't copy CCR registers. 2890b57cec5SDimitry Andric return RC; 2900b57cec5SDimitry Andric } 2910b57cec5SDimitry Andric 2920b57cec5SDimitry Andric unsigned 2930b57cec5SDimitry Andric ARMBaseRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC, 2940b57cec5SDimitry Andric MachineFunction &MF) const { 2950b57cec5SDimitry Andric const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); 2960b57cec5SDimitry Andric const ARMFrameLowering *TFI = getFrameLowering(MF); 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric switch (RC->getID()) { 2990b57cec5SDimitry Andric default: 3000b57cec5SDimitry Andric return 0; 3010b57cec5SDimitry Andric case ARM::tGPRRegClassID: { 3020b57cec5SDimitry Andric // hasFP ends up calling getMaxCallFrameComputed() which may not be 3030b57cec5SDimitry Andric // available when getPressureLimit() is called as part of 3040b57cec5SDimitry Andric // ScheduleDAGRRList. 3050b57cec5SDimitry Andric bool HasFP = MF.getFrameInfo().isMaxCallFrameSizeComputed() 3060b57cec5SDimitry Andric ? TFI->hasFP(MF) : true; 3070b57cec5SDimitry Andric return 5 - HasFP; 3080b57cec5SDimitry Andric } 3090b57cec5SDimitry Andric case ARM::GPRRegClassID: { 3100b57cec5SDimitry Andric bool HasFP = MF.getFrameInfo().isMaxCallFrameSizeComputed() 3110b57cec5SDimitry Andric ? TFI->hasFP(MF) : true; 3120b57cec5SDimitry Andric return 10 - HasFP - (STI.isR9Reserved() ? 1 : 0); 3130b57cec5SDimitry Andric } 3140b57cec5SDimitry Andric case ARM::SPRRegClassID: // Currently not used as 'rep' register class. 3150b57cec5SDimitry Andric case ARM::DPRRegClassID: 3160b57cec5SDimitry Andric return 32 - 10; 3170b57cec5SDimitry Andric } 3180b57cec5SDimitry Andric } 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric // Get the other register in a GPRPair. 3215ffd83dbSDimitry Andric static MCPhysReg getPairedGPR(MCPhysReg Reg, bool Odd, 3225ffd83dbSDimitry Andric const MCRegisterInfo *RI) { 3230b57cec5SDimitry Andric for (MCSuperRegIterator Supers(Reg, RI); Supers.isValid(); ++Supers) 3240b57cec5SDimitry Andric if (ARM::GPRPairRegClass.contains(*Supers)) 3250b57cec5SDimitry Andric return RI->getSubReg(*Supers, Odd ? ARM::gsub_1 : ARM::gsub_0); 3260b57cec5SDimitry Andric return 0; 3270b57cec5SDimitry Andric } 3280b57cec5SDimitry Andric 3290b57cec5SDimitry Andric // Resolve the RegPairEven / RegPairOdd register allocator hints. 3305ffd83dbSDimitry Andric bool ARMBaseRegisterInfo::getRegAllocationHints( 3315ffd83dbSDimitry Andric Register VirtReg, ArrayRef<MCPhysReg> Order, 3325ffd83dbSDimitry Andric SmallVectorImpl<MCPhysReg> &Hints, const MachineFunction &MF, 3335ffd83dbSDimitry Andric const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const { 3340b57cec5SDimitry Andric const MachineRegisterInfo &MRI = MF.getRegInfo(); 3355ffd83dbSDimitry Andric std::pair<Register, Register> Hint = MRI.getRegAllocationHint(VirtReg); 3360b57cec5SDimitry Andric 3370b57cec5SDimitry Andric unsigned Odd; 3380b57cec5SDimitry Andric switch (Hint.first) { 3390b57cec5SDimitry Andric case ARMRI::RegPairEven: 3400b57cec5SDimitry Andric Odd = 0; 3410b57cec5SDimitry Andric break; 3420b57cec5SDimitry Andric case ARMRI::RegPairOdd: 3430b57cec5SDimitry Andric Odd = 1; 3440b57cec5SDimitry Andric break; 345e8d8bef9SDimitry Andric case ARMRI::RegLR: 3460b57cec5SDimitry Andric TargetRegisterInfo::getRegAllocationHints(VirtReg, Order, Hints, MF, VRM); 347e8d8bef9SDimitry Andric if (MRI.getRegClass(VirtReg)->contains(ARM::LR)) 348e8d8bef9SDimitry Andric Hints.push_back(ARM::LR); 3490b57cec5SDimitry Andric return false; 350e8d8bef9SDimitry Andric default: 351e8d8bef9SDimitry Andric return TargetRegisterInfo::getRegAllocationHints(VirtReg, Order, Hints, MF, VRM); 3520b57cec5SDimitry Andric } 3530b57cec5SDimitry Andric 3540b57cec5SDimitry Andric // This register should preferably be even (Odd == 0) or odd (Odd == 1). 3550b57cec5SDimitry Andric // Check if the other part of the pair has already been assigned, and provide 3560b57cec5SDimitry Andric // the paired register as the first hint. 3575ffd83dbSDimitry Andric Register Paired = Hint.second; 3585ffd83dbSDimitry Andric if (!Paired) 3590b57cec5SDimitry Andric return false; 3600b57cec5SDimitry Andric 3615ffd83dbSDimitry Andric Register PairedPhys; 3625ffd83dbSDimitry Andric if (Paired.isPhysical()) { 3630b57cec5SDimitry Andric PairedPhys = Paired; 3640b57cec5SDimitry Andric } else if (VRM && VRM->hasPhys(Paired)) { 3650b57cec5SDimitry Andric PairedPhys = getPairedGPR(VRM->getPhys(Paired), Odd, this); 3660b57cec5SDimitry Andric } 3670b57cec5SDimitry Andric 3680b57cec5SDimitry Andric // First prefer the paired physreg. 3690b57cec5SDimitry Andric if (PairedPhys && is_contained(Order, PairedPhys)) 3700b57cec5SDimitry Andric Hints.push_back(PairedPhys); 3710b57cec5SDimitry Andric 3720b57cec5SDimitry Andric // Then prefer even or odd registers. 3735ffd83dbSDimitry Andric for (MCPhysReg Reg : Order) { 3740b57cec5SDimitry Andric if (Reg == PairedPhys || (getEncodingValue(Reg) & 1) != Odd) 3750b57cec5SDimitry Andric continue; 3760b57cec5SDimitry Andric // Don't provide hints that are paired to a reserved register. 3775ffd83dbSDimitry Andric MCPhysReg Paired = getPairedGPR(Reg, !Odd, this); 3780b57cec5SDimitry Andric if (!Paired || MRI.isReserved(Paired)) 3790b57cec5SDimitry Andric continue; 3800b57cec5SDimitry Andric Hints.push_back(Reg); 3810b57cec5SDimitry Andric } 3820b57cec5SDimitry Andric return false; 3830b57cec5SDimitry Andric } 3840b57cec5SDimitry Andric 3855ffd83dbSDimitry Andric void ARMBaseRegisterInfo::updateRegAllocHint(Register Reg, Register NewReg, 3860b57cec5SDimitry Andric MachineFunction &MF) const { 3870b57cec5SDimitry Andric MachineRegisterInfo *MRI = &MF.getRegInfo(); 3885ffd83dbSDimitry Andric std::pair<Register, Register> Hint = MRI->getRegAllocationHint(Reg); 3895ffd83dbSDimitry Andric if ((Hint.first == ARMRI::RegPairOdd || Hint.first == ARMRI::RegPairEven) && 3905ffd83dbSDimitry Andric Hint.second.isVirtual()) { 3910b57cec5SDimitry Andric // If 'Reg' is one of the even / odd register pair and it's now changed 3920b57cec5SDimitry Andric // (e.g. coalesced) into a different register. The other register of the 3930b57cec5SDimitry Andric // pair allocation hint must be updated to reflect the relationship 3940b57cec5SDimitry Andric // change. 3955ffd83dbSDimitry Andric Register OtherReg = Hint.second; 3960b57cec5SDimitry Andric Hint = MRI->getRegAllocationHint(OtherReg); 3970b57cec5SDimitry Andric // Make sure the pair has not already divorced. 3980b57cec5SDimitry Andric if (Hint.second == Reg) { 3990b57cec5SDimitry Andric MRI->setRegAllocationHint(OtherReg, Hint.first, NewReg); 4008bcb0991SDimitry Andric if (Register::isVirtualRegister(NewReg)) 4010b57cec5SDimitry Andric MRI->setRegAllocationHint(NewReg, 4025ffd83dbSDimitry Andric Hint.first == ARMRI::RegPairOdd 4035ffd83dbSDimitry Andric ? ARMRI::RegPairEven 4045ffd83dbSDimitry Andric : ARMRI::RegPairOdd, 4055ffd83dbSDimitry Andric OtherReg); 4060b57cec5SDimitry Andric } 4070b57cec5SDimitry Andric } 4080b57cec5SDimitry Andric } 4090b57cec5SDimitry Andric 4100b57cec5SDimitry Andric bool ARMBaseRegisterInfo::hasBasePointer(const MachineFunction &MF) const { 4110b57cec5SDimitry Andric const MachineFrameInfo &MFI = MF.getFrameInfo(); 4120b57cec5SDimitry Andric const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 4130b57cec5SDimitry Andric const ARMFrameLowering *TFI = getFrameLowering(MF); 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric // If we have stack realignment and VLAs, we have no pointer to use to 4160b57cec5SDimitry Andric // access the stack. If we have stack realignment, and a large call frame, 4170b57cec5SDimitry Andric // we have no place to allocate the emergency spill slot. 418fe6060f1SDimitry Andric if (hasStackRealignment(MF) && !TFI->hasReservedCallFrame(MF)) 4190b57cec5SDimitry Andric return true; 4200b57cec5SDimitry Andric 4210b57cec5SDimitry Andric // Thumb has trouble with negative offsets from the FP. Thumb2 has a limited 422480093f4SDimitry Andric // negative range for ldr/str (255), and Thumb1 is positive offsets only. 4230b57cec5SDimitry Andric // 4240b57cec5SDimitry Andric // It's going to be better to use the SP or Base Pointer instead. When there 4250b57cec5SDimitry Andric // are variable sized objects, we can't reference off of the SP, so we 4260b57cec5SDimitry Andric // reserve a Base Pointer. 4270b57cec5SDimitry Andric // 4280b57cec5SDimitry Andric // For Thumb2, estimate whether a negative offset from the frame pointer 4290b57cec5SDimitry Andric // will be sufficient to reach the whole stack frame. If a function has a 4300b57cec5SDimitry Andric // smallish frame, it's less likely to have lots of spills and callee saved 4310b57cec5SDimitry Andric // space, so it's all more likely to be within range of the frame pointer. 4320b57cec5SDimitry Andric // If it's wrong, the scavenger will still enable access to work, it just 4330b57cec5SDimitry Andric // won't be optimal. (We should always be able to reach the emergency 4340b57cec5SDimitry Andric // spill slot from the frame pointer.) 4350b57cec5SDimitry Andric if (AFI->isThumb2Function() && MFI.hasVarSizedObjects() && 4360b57cec5SDimitry Andric MFI.getLocalFrameSize() >= 128) 4370b57cec5SDimitry Andric return true; 4380b57cec5SDimitry Andric // For Thumb1, if sp moves, nothing is in range, so force a base pointer. 4390b57cec5SDimitry Andric // This is necessary for correctness in cases where we need an emergency 4400b57cec5SDimitry Andric // spill slot. (In Thumb1, we can't use a negative offset from the frame 4410b57cec5SDimitry Andric // pointer.) 4420b57cec5SDimitry Andric if (AFI->isThumb1OnlyFunction() && !TFI->hasReservedCallFrame(MF)) 4430b57cec5SDimitry Andric return true; 4440b57cec5SDimitry Andric return false; 4450b57cec5SDimitry Andric } 4460b57cec5SDimitry Andric 4470b57cec5SDimitry Andric bool ARMBaseRegisterInfo::canRealignStack(const MachineFunction &MF) const { 4480b57cec5SDimitry Andric const MachineRegisterInfo *MRI = &MF.getRegInfo(); 4490b57cec5SDimitry Andric const ARMFrameLowering *TFI = getFrameLowering(MF); 450fe6060f1SDimitry Andric const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); 4510b57cec5SDimitry Andric // We can't realign the stack if: 4520b57cec5SDimitry Andric // 1. Dynamic stack realignment is explicitly disabled, 4530b57cec5SDimitry Andric // 2. There are VLAs in the function and the base pointer is disabled. 4540b57cec5SDimitry Andric if (!TargetRegisterInfo::canRealignStack(MF)) 4550b57cec5SDimitry Andric return false; 4560b57cec5SDimitry Andric // Stack realignment requires a frame pointer. If we already started 4570b57cec5SDimitry Andric // register allocation with frame pointer elimination, it is too late now. 458fe6060f1SDimitry Andric if (!MRI->canReserveReg(STI.getFramePointerReg())) 4590b57cec5SDimitry Andric return false; 4600b57cec5SDimitry Andric // We may also need a base pointer if there are dynamic allocas or stack 4610b57cec5SDimitry Andric // pointer adjustments around calls. 4620b57cec5SDimitry Andric if (TFI->hasReservedCallFrame(MF)) 4630b57cec5SDimitry Andric return true; 4640b57cec5SDimitry Andric // A base pointer is required and allowed. Check that it isn't too late to 4650b57cec5SDimitry Andric // reserve it. 4660b57cec5SDimitry Andric return MRI->canReserveReg(BasePtr); 4670b57cec5SDimitry Andric } 4680b57cec5SDimitry Andric 4690b57cec5SDimitry Andric bool ARMBaseRegisterInfo:: 4700b57cec5SDimitry Andric cannotEliminateFrame(const MachineFunction &MF) const { 4710b57cec5SDimitry Andric const MachineFrameInfo &MFI = MF.getFrameInfo(); 4720b57cec5SDimitry Andric if (MF.getTarget().Options.DisableFramePointerElim(MF) && MFI.adjustsStack()) 4730b57cec5SDimitry Andric return true; 474fe6060f1SDimitry Andric return MFI.hasVarSizedObjects() || MFI.isFrameAddressTaken() || 475fe6060f1SDimitry Andric hasStackRealignment(MF); 4760b57cec5SDimitry Andric } 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andric Register 4790b57cec5SDimitry Andric ARMBaseRegisterInfo::getFrameRegister(const MachineFunction &MF) const { 4800b57cec5SDimitry Andric const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); 4810b57cec5SDimitry Andric const ARMFrameLowering *TFI = getFrameLowering(MF); 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andric if (TFI->hasFP(MF)) 484fe6060f1SDimitry Andric return STI.getFramePointerReg(); 4850b57cec5SDimitry Andric return ARM::SP; 4860b57cec5SDimitry Andric } 4870b57cec5SDimitry Andric 4880b57cec5SDimitry Andric /// emitLoadConstPool - Emits a load from constpool to materialize the 4890b57cec5SDimitry Andric /// specified immediate. 4900b57cec5SDimitry Andric void ARMBaseRegisterInfo::emitLoadConstPool( 4910b57cec5SDimitry Andric MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 4925ffd83dbSDimitry Andric const DebugLoc &dl, Register DestReg, unsigned SubIdx, int Val, 4935ffd83dbSDimitry Andric ARMCC::CondCodes Pred, Register PredReg, unsigned MIFlags) const { 4940b57cec5SDimitry Andric MachineFunction &MF = *MBB.getParent(); 4950b57cec5SDimitry Andric const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); 4960b57cec5SDimitry Andric MachineConstantPool *ConstantPool = MF.getConstantPool(); 4970b57cec5SDimitry Andric const Constant *C = 4980b57cec5SDimitry Andric ConstantInt::get(Type::getInt32Ty(MF.getFunction().getContext()), Val); 4995ffd83dbSDimitry Andric unsigned Idx = ConstantPool->getConstantPoolIndex(C, Align(4)); 5000b57cec5SDimitry Andric 5010b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(ARM::LDRcp)) 5020b57cec5SDimitry Andric .addReg(DestReg, getDefRegState(true), SubIdx) 5030b57cec5SDimitry Andric .addConstantPoolIndex(Idx) 5040b57cec5SDimitry Andric .addImm(0) 5050b57cec5SDimitry Andric .add(predOps(Pred, PredReg)) 5060b57cec5SDimitry Andric .setMIFlags(MIFlags); 5070b57cec5SDimitry Andric } 5080b57cec5SDimitry Andric 5090b57cec5SDimitry Andric bool ARMBaseRegisterInfo:: 5100b57cec5SDimitry Andric requiresRegisterScavenging(const MachineFunction &MF) const { 5110b57cec5SDimitry Andric return true; 5120b57cec5SDimitry Andric } 5130b57cec5SDimitry Andric 5140b57cec5SDimitry Andric bool ARMBaseRegisterInfo:: 5150b57cec5SDimitry Andric requiresFrameIndexScavenging(const MachineFunction &MF) const { 5160b57cec5SDimitry Andric return true; 5170b57cec5SDimitry Andric } 5180b57cec5SDimitry Andric 5190b57cec5SDimitry Andric bool ARMBaseRegisterInfo:: 5200b57cec5SDimitry Andric requiresVirtualBaseRegisters(const MachineFunction &MF) const { 5210b57cec5SDimitry Andric return true; 5220b57cec5SDimitry Andric } 5230b57cec5SDimitry Andric 5240b57cec5SDimitry Andric int64_t ARMBaseRegisterInfo:: 5250b57cec5SDimitry Andric getFrameIndexInstrOffset(const MachineInstr *MI, int Idx) const { 5260b57cec5SDimitry Andric const MCInstrDesc &Desc = MI->getDesc(); 5270b57cec5SDimitry Andric unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 5280b57cec5SDimitry Andric int64_t InstrOffs = 0; 5290b57cec5SDimitry Andric int Scale = 1; 5300b57cec5SDimitry Andric unsigned ImmIdx = 0; 5310b57cec5SDimitry Andric switch (AddrMode) { 5320b57cec5SDimitry Andric case ARMII::AddrModeT2_i8: 5330eae32dcSDimitry Andric case ARMII::AddrModeT2_i8neg: 5340eae32dcSDimitry Andric case ARMII::AddrModeT2_i8pos: 5350b57cec5SDimitry Andric case ARMII::AddrModeT2_i12: 5360b57cec5SDimitry Andric case ARMII::AddrMode_i12: 5370b57cec5SDimitry Andric InstrOffs = MI->getOperand(Idx+1).getImm(); 5380b57cec5SDimitry Andric Scale = 1; 5390b57cec5SDimitry Andric break; 5400b57cec5SDimitry Andric case ARMII::AddrMode5: { 5410b57cec5SDimitry Andric // VFP address mode. 5420b57cec5SDimitry Andric const MachineOperand &OffOp = MI->getOperand(Idx+1); 5430b57cec5SDimitry Andric InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm()); 5440b57cec5SDimitry Andric if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub) 5450b57cec5SDimitry Andric InstrOffs = -InstrOffs; 5460b57cec5SDimitry Andric Scale = 4; 5470b57cec5SDimitry Andric break; 5480b57cec5SDimitry Andric } 5490b57cec5SDimitry Andric case ARMII::AddrMode2: 5500b57cec5SDimitry Andric ImmIdx = Idx+2; 5510b57cec5SDimitry Andric InstrOffs = ARM_AM::getAM2Offset(MI->getOperand(ImmIdx).getImm()); 5520b57cec5SDimitry Andric if (ARM_AM::getAM2Op(MI->getOperand(ImmIdx).getImm()) == ARM_AM::sub) 5530b57cec5SDimitry Andric InstrOffs = -InstrOffs; 5540b57cec5SDimitry Andric break; 5550b57cec5SDimitry Andric case ARMII::AddrMode3: 5560b57cec5SDimitry Andric ImmIdx = Idx+2; 5570b57cec5SDimitry Andric InstrOffs = ARM_AM::getAM3Offset(MI->getOperand(ImmIdx).getImm()); 5580b57cec5SDimitry Andric if (ARM_AM::getAM3Op(MI->getOperand(ImmIdx).getImm()) == ARM_AM::sub) 5590b57cec5SDimitry Andric InstrOffs = -InstrOffs; 5600b57cec5SDimitry Andric break; 5610b57cec5SDimitry Andric case ARMII::AddrModeT1_s: 5620b57cec5SDimitry Andric ImmIdx = Idx+1; 5630b57cec5SDimitry Andric InstrOffs = MI->getOperand(ImmIdx).getImm(); 5640b57cec5SDimitry Andric Scale = 4; 5650b57cec5SDimitry Andric break; 5660b57cec5SDimitry Andric default: 5670b57cec5SDimitry Andric llvm_unreachable("Unsupported addressing mode!"); 5680b57cec5SDimitry Andric } 5690b57cec5SDimitry Andric 5700b57cec5SDimitry Andric return InstrOffs * Scale; 5710b57cec5SDimitry Andric } 5720b57cec5SDimitry Andric 5730b57cec5SDimitry Andric /// needsFrameBaseReg - Returns true if the instruction's frame index 5740b57cec5SDimitry Andric /// reference would be better served by a base register other than FP 5750b57cec5SDimitry Andric /// or SP. Used by LocalStackFrameAllocation to determine which frame index 5760b57cec5SDimitry Andric /// references it should create new base registers for. 5770b57cec5SDimitry Andric bool ARMBaseRegisterInfo:: 5780b57cec5SDimitry Andric needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const { 5790b57cec5SDimitry Andric for (unsigned i = 0; !MI->getOperand(i).isFI(); ++i) { 5800b57cec5SDimitry Andric assert(i < MI->getNumOperands() &&"Instr doesn't have FrameIndex operand!"); 5810b57cec5SDimitry Andric } 5820b57cec5SDimitry Andric 5830b57cec5SDimitry Andric // It's the load/store FI references that cause issues, as it can be difficult 5840b57cec5SDimitry Andric // to materialize the offset if it won't fit in the literal field. Estimate 5850b57cec5SDimitry Andric // based on the size of the local frame and some conservative assumptions 5860b57cec5SDimitry Andric // about the rest of the stack frame (note, this is pre-regalloc, so 5870b57cec5SDimitry Andric // we don't know everything for certain yet) whether this offset is likely 5880b57cec5SDimitry Andric // to be out of range of the immediate. Return true if so. 5890b57cec5SDimitry Andric 5900b57cec5SDimitry Andric // We only generate virtual base registers for loads and stores, so 5910b57cec5SDimitry Andric // return false for everything else. 5920b57cec5SDimitry Andric unsigned Opc = MI->getOpcode(); 5930b57cec5SDimitry Andric switch (Opc) { 5940b57cec5SDimitry Andric case ARM::LDRi12: case ARM::LDRH: case ARM::LDRBi12: 5950b57cec5SDimitry Andric case ARM::STRi12: case ARM::STRH: case ARM::STRBi12: 5960b57cec5SDimitry Andric case ARM::t2LDRi12: case ARM::t2LDRi8: 5970b57cec5SDimitry Andric case ARM::t2STRi12: case ARM::t2STRi8: 5980b57cec5SDimitry Andric case ARM::VLDRS: case ARM::VLDRD: 5990b57cec5SDimitry Andric case ARM::VSTRS: case ARM::VSTRD: 6000b57cec5SDimitry Andric case ARM::tSTRspi: case ARM::tLDRspi: 6010b57cec5SDimitry Andric break; 6020b57cec5SDimitry Andric default: 6030b57cec5SDimitry Andric return false; 6040b57cec5SDimitry Andric } 6050b57cec5SDimitry Andric 6060b57cec5SDimitry Andric // Without a virtual base register, if the function has variable sized 6070b57cec5SDimitry Andric // objects, all fixed-size local references will be via the frame pointer, 6080b57cec5SDimitry Andric // Approximate the offset and see if it's legal for the instruction. 6090b57cec5SDimitry Andric // Note that the incoming offset is based on the SP value at function entry, 6100b57cec5SDimitry Andric // so it'll be negative. 6110b57cec5SDimitry Andric MachineFunction &MF = *MI->getParent()->getParent(); 6120b57cec5SDimitry Andric const ARMFrameLowering *TFI = getFrameLowering(MF); 6130b57cec5SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo(); 6140b57cec5SDimitry Andric ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 6150b57cec5SDimitry Andric 6160b57cec5SDimitry Andric // Estimate an offset from the frame pointer. 6170b57cec5SDimitry Andric // Conservatively assume all callee-saved registers get pushed. R4-R6 6180b57cec5SDimitry Andric // will be earlier than the FP, so we ignore those. 6190b57cec5SDimitry Andric // R7, LR 6200b57cec5SDimitry Andric int64_t FPOffset = Offset - 8; 6210b57cec5SDimitry Andric // ARM and Thumb2 functions also need to consider R8-R11 and D8-D15 6220b57cec5SDimitry Andric if (!AFI->isThumbFunction() || !AFI->isThumb1OnlyFunction()) 6230b57cec5SDimitry Andric FPOffset -= 80; 6240b57cec5SDimitry Andric // Estimate an offset from the stack pointer. 6250b57cec5SDimitry Andric // The incoming offset is relating to the SP at the start of the function, 6260b57cec5SDimitry Andric // but when we access the local it'll be relative to the SP after local 6270b57cec5SDimitry Andric // allocation, so adjust our SP-relative offset by that allocation size. 6280b57cec5SDimitry Andric Offset += MFI.getLocalFrameSize(); 6290b57cec5SDimitry Andric // Assume that we'll have at least some spill slots allocated. 6300b57cec5SDimitry Andric // FIXME: This is a total SWAG number. We should run some statistics 6310b57cec5SDimitry Andric // and pick a real one. 6320b57cec5SDimitry Andric Offset += 128; // 128 bytes of spill slots 6330b57cec5SDimitry Andric 6340b57cec5SDimitry Andric // If there's a frame pointer and the addressing mode allows it, try using it. 6350b57cec5SDimitry Andric // The FP is only available if there is no dynamic realignment. We 6360b57cec5SDimitry Andric // don't know for sure yet whether we'll need that, so we guess based 6370b57cec5SDimitry Andric // on whether there are any local variables that would trigger it. 6380b57cec5SDimitry Andric if (TFI->hasFP(MF) && 6395ffd83dbSDimitry Andric !((MFI.getLocalFrameMaxAlign() > TFI->getStackAlign()) && 6405ffd83dbSDimitry Andric canRealignStack(MF))) { 6410b57cec5SDimitry Andric if (isFrameOffsetLegal(MI, getFrameRegister(MF), FPOffset)) 6420b57cec5SDimitry Andric return false; 6430b57cec5SDimitry Andric } 6440b57cec5SDimitry Andric // If we can reference via the stack pointer, try that. 6450b57cec5SDimitry Andric // FIXME: This (and the code that resolves the references) can be improved 6460b57cec5SDimitry Andric // to only disallow SP relative references in the live range of 6470b57cec5SDimitry Andric // the VLA(s). In practice, it's unclear how much difference that 6480b57cec5SDimitry Andric // would make, but it may be worth doing. 6490b57cec5SDimitry Andric if (!MFI.hasVarSizedObjects() && isFrameOffsetLegal(MI, ARM::SP, Offset)) 6500b57cec5SDimitry Andric return false; 6510b57cec5SDimitry Andric 6520b57cec5SDimitry Andric // The offset likely isn't legal, we want to allocate a virtual base register. 6530b57cec5SDimitry Andric return true; 6540b57cec5SDimitry Andric } 6550b57cec5SDimitry Andric 6560b57cec5SDimitry Andric /// materializeFrameBaseRegister - Insert defining instruction(s) for BaseReg to 6570b57cec5SDimitry Andric /// be a pointer to FrameIdx at the beginning of the basic block. 658e8d8bef9SDimitry Andric Register 659e8d8bef9SDimitry Andric ARMBaseRegisterInfo::materializeFrameBaseRegister(MachineBasicBlock *MBB, 6605ffd83dbSDimitry Andric int FrameIdx, 6610b57cec5SDimitry Andric int64_t Offset) const { 6620b57cec5SDimitry Andric ARMFunctionInfo *AFI = MBB->getParent()->getInfo<ARMFunctionInfo>(); 6630b57cec5SDimitry Andric unsigned ADDriOpc = !AFI->isThumbFunction() ? ARM::ADDri : 6640b57cec5SDimitry Andric (AFI->isThumb1OnlyFunction() ? ARM::tADDframe : ARM::t2ADDri); 6650b57cec5SDimitry Andric 6660b57cec5SDimitry Andric MachineBasicBlock::iterator Ins = MBB->begin(); 6670b57cec5SDimitry Andric DebugLoc DL; // Defaults to "unknown" 6680b57cec5SDimitry Andric if (Ins != MBB->end()) 6690b57cec5SDimitry Andric DL = Ins->getDebugLoc(); 6700b57cec5SDimitry Andric 6710b57cec5SDimitry Andric const MachineFunction &MF = *MBB->getParent(); 6720b57cec5SDimitry Andric MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo(); 6730b57cec5SDimitry Andric const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); 6740b57cec5SDimitry Andric const MCInstrDesc &MCID = TII.get(ADDriOpc); 675e8d8bef9SDimitry Andric Register BaseReg = MRI.createVirtualRegister(&ARM::GPRRegClass); 6760b57cec5SDimitry Andric MRI.constrainRegClass(BaseReg, TII.getRegClass(MCID, 0, this, MF)); 6770b57cec5SDimitry Andric 6780b57cec5SDimitry Andric MachineInstrBuilder MIB = BuildMI(*MBB, Ins, DL, MCID, BaseReg) 6790b57cec5SDimitry Andric .addFrameIndex(FrameIdx).addImm(Offset); 6800b57cec5SDimitry Andric 6810b57cec5SDimitry Andric if (!AFI->isThumb1OnlyFunction()) 6820b57cec5SDimitry Andric MIB.add(predOps(ARMCC::AL)).add(condCodeOp()); 683e8d8bef9SDimitry Andric 684e8d8bef9SDimitry Andric return BaseReg; 6850b57cec5SDimitry Andric } 6860b57cec5SDimitry Andric 6875ffd83dbSDimitry Andric void ARMBaseRegisterInfo::resolveFrameIndex(MachineInstr &MI, Register BaseReg, 6880b57cec5SDimitry Andric int64_t Offset) const { 6890b57cec5SDimitry Andric MachineBasicBlock &MBB = *MI.getParent(); 6900b57cec5SDimitry Andric MachineFunction &MF = *MBB.getParent(); 6910b57cec5SDimitry Andric const ARMBaseInstrInfo &TII = 6920b57cec5SDimitry Andric *static_cast<const ARMBaseInstrInfo *>(MF.getSubtarget().getInstrInfo()); 6930b57cec5SDimitry Andric ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 6940b57cec5SDimitry Andric int Off = Offset; // ARM doesn't need the general 64-bit offsets 6950b57cec5SDimitry Andric unsigned i = 0; 6960b57cec5SDimitry Andric 6970b57cec5SDimitry Andric assert(!AFI->isThumb1OnlyFunction() && 6980b57cec5SDimitry Andric "This resolveFrameIndex does not support Thumb1!"); 6990b57cec5SDimitry Andric 7000b57cec5SDimitry Andric while (!MI.getOperand(i).isFI()) { 7010b57cec5SDimitry Andric ++i; 7020b57cec5SDimitry Andric assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 7030b57cec5SDimitry Andric } 7040b57cec5SDimitry Andric bool Done = false; 7050b57cec5SDimitry Andric if (!AFI->isThumbFunction()) 7060b57cec5SDimitry Andric Done = rewriteARMFrameIndex(MI, i, BaseReg, Off, TII); 7070b57cec5SDimitry Andric else { 7080b57cec5SDimitry Andric assert(AFI->isThumb2Function()); 7098bcb0991SDimitry Andric Done = rewriteT2FrameIndex(MI, i, BaseReg, Off, TII, this); 7100b57cec5SDimitry Andric } 7110b57cec5SDimitry Andric assert(Done && "Unable to resolve frame index!"); 7120b57cec5SDimitry Andric (void)Done; 7130b57cec5SDimitry Andric } 7140b57cec5SDimitry Andric 7155ffd83dbSDimitry Andric bool ARMBaseRegisterInfo::isFrameOffsetLegal(const MachineInstr *MI, 7165ffd83dbSDimitry Andric Register BaseReg, 7170b57cec5SDimitry Andric int64_t Offset) const { 7180b57cec5SDimitry Andric const MCInstrDesc &Desc = MI->getDesc(); 7190b57cec5SDimitry Andric unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 7200b57cec5SDimitry Andric unsigned i = 0; 7210b57cec5SDimitry Andric for (; !MI->getOperand(i).isFI(); ++i) 7220b57cec5SDimitry Andric assert(i+1 < MI->getNumOperands() && "Instr doesn't have FrameIndex operand!"); 7230b57cec5SDimitry Andric 7240b57cec5SDimitry Andric // AddrMode4 and AddrMode6 cannot handle any offset. 7250b57cec5SDimitry Andric if (AddrMode == ARMII::AddrMode4 || AddrMode == ARMII::AddrMode6) 7260b57cec5SDimitry Andric return Offset == 0; 7270b57cec5SDimitry Andric 7280b57cec5SDimitry Andric unsigned NumBits = 0; 7290b57cec5SDimitry Andric unsigned Scale = 1; 7300b57cec5SDimitry Andric bool isSigned = true; 7310b57cec5SDimitry Andric switch (AddrMode) { 7320b57cec5SDimitry Andric case ARMII::AddrModeT2_i8: 7330eae32dcSDimitry Andric case ARMII::AddrModeT2_i8pos: 7340eae32dcSDimitry Andric case ARMII::AddrModeT2_i8neg: 7350b57cec5SDimitry Andric case ARMII::AddrModeT2_i12: 7360b57cec5SDimitry Andric // i8 supports only negative, and i12 supports only positive, so 7370b57cec5SDimitry Andric // based on Offset sign, consider the appropriate instruction 7380b57cec5SDimitry Andric Scale = 1; 7390b57cec5SDimitry Andric if (Offset < 0) { 7400b57cec5SDimitry Andric NumBits = 8; 7410b57cec5SDimitry Andric Offset = -Offset; 7420b57cec5SDimitry Andric } else { 7430b57cec5SDimitry Andric NumBits = 12; 7440b57cec5SDimitry Andric } 7450b57cec5SDimitry Andric break; 7460b57cec5SDimitry Andric case ARMII::AddrMode5: 7470b57cec5SDimitry Andric // VFP address mode. 7480b57cec5SDimitry Andric NumBits = 8; 7490b57cec5SDimitry Andric Scale = 4; 7500b57cec5SDimitry Andric break; 7510b57cec5SDimitry Andric case ARMII::AddrMode_i12: 7520b57cec5SDimitry Andric case ARMII::AddrMode2: 7530b57cec5SDimitry Andric NumBits = 12; 7540b57cec5SDimitry Andric break; 7550b57cec5SDimitry Andric case ARMII::AddrMode3: 7560b57cec5SDimitry Andric NumBits = 8; 7570b57cec5SDimitry Andric break; 7580b57cec5SDimitry Andric case ARMII::AddrModeT1_s: 7590b57cec5SDimitry Andric NumBits = (BaseReg == ARM::SP ? 8 : 5); 7600b57cec5SDimitry Andric Scale = 4; 7610b57cec5SDimitry Andric isSigned = false; 7620b57cec5SDimitry Andric break; 7630b57cec5SDimitry Andric default: 7640b57cec5SDimitry Andric llvm_unreachable("Unsupported addressing mode!"); 7650b57cec5SDimitry Andric } 7660b57cec5SDimitry Andric 7670b57cec5SDimitry Andric Offset += getFrameIndexInstrOffset(MI, i); 7680b57cec5SDimitry Andric // Make sure the offset is encodable for instructions that scale the 7690b57cec5SDimitry Andric // immediate. 7700b57cec5SDimitry Andric if ((Offset & (Scale-1)) != 0) 7710b57cec5SDimitry Andric return false; 7720b57cec5SDimitry Andric 7730b57cec5SDimitry Andric if (isSigned && Offset < 0) 7740b57cec5SDimitry Andric Offset = -Offset; 7750b57cec5SDimitry Andric 7760b57cec5SDimitry Andric unsigned Mask = (1 << NumBits) - 1; 7770b57cec5SDimitry Andric if ((unsigned)Offset <= Mask * Scale) 7780b57cec5SDimitry Andric return true; 7790b57cec5SDimitry Andric 7800b57cec5SDimitry Andric return false; 7810b57cec5SDimitry Andric } 7820b57cec5SDimitry Andric 7830b57cec5SDimitry Andric void 7840b57cec5SDimitry Andric ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 7850b57cec5SDimitry Andric int SPAdj, unsigned FIOperandNum, 7860b57cec5SDimitry Andric RegScavenger *RS) const { 7870b57cec5SDimitry Andric MachineInstr &MI = *II; 7880b57cec5SDimitry Andric MachineBasicBlock &MBB = *MI.getParent(); 7890b57cec5SDimitry Andric MachineFunction &MF = *MBB.getParent(); 7900b57cec5SDimitry Andric const ARMBaseInstrInfo &TII = 7910b57cec5SDimitry Andric *static_cast<const ARMBaseInstrInfo *>(MF.getSubtarget().getInstrInfo()); 7920b57cec5SDimitry Andric const ARMFrameLowering *TFI = getFrameLowering(MF); 7930b57cec5SDimitry Andric ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 7940b57cec5SDimitry Andric assert(!AFI->isThumb1OnlyFunction() && 7950b57cec5SDimitry Andric "This eliminateFrameIndex does not support Thumb1!"); 7960b57cec5SDimitry Andric int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); 7975ffd83dbSDimitry Andric Register FrameReg; 7980b57cec5SDimitry Andric 7990b57cec5SDimitry Andric int Offset = TFI->ResolveFrameIndexReference(MF, FrameIndex, FrameReg, SPAdj); 8000b57cec5SDimitry Andric 8010b57cec5SDimitry Andric // PEI::scavengeFrameVirtualRegs() cannot accurately track SPAdj because the 8020b57cec5SDimitry Andric // call frame setup/destroy instructions have already been eliminated. That 8030b57cec5SDimitry Andric // means the stack pointer cannot be used to access the emergency spill slot 8040b57cec5SDimitry Andric // when !hasReservedCallFrame(). 8050b57cec5SDimitry Andric #ifndef NDEBUG 8060b57cec5SDimitry Andric if (RS && FrameReg == ARM::SP && RS->isScavengingFrameIndex(FrameIndex)){ 8070b57cec5SDimitry Andric assert(TFI->hasReservedCallFrame(MF) && 8080b57cec5SDimitry Andric "Cannot use SP to access the emergency spill slot in " 8090b57cec5SDimitry Andric "functions without a reserved call frame"); 8100b57cec5SDimitry Andric assert(!MF.getFrameInfo().hasVarSizedObjects() && 8110b57cec5SDimitry Andric "Cannot use SP to access the emergency spill slot in " 8120b57cec5SDimitry Andric "functions with variable sized frame objects"); 8130b57cec5SDimitry Andric } 8140b57cec5SDimitry Andric #endif // NDEBUG 8150b57cec5SDimitry Andric 8160b57cec5SDimitry Andric assert(!MI.isDebugValue() && "DBG_VALUEs should be handled in target-independent code"); 8170b57cec5SDimitry Andric 8180b57cec5SDimitry Andric // Modify MI as necessary to handle as much of 'Offset' as possible 8190b57cec5SDimitry Andric bool Done = false; 8200b57cec5SDimitry Andric if (!AFI->isThumbFunction()) 8210b57cec5SDimitry Andric Done = rewriteARMFrameIndex(MI, FIOperandNum, FrameReg, Offset, TII); 8220b57cec5SDimitry Andric else { 8230b57cec5SDimitry Andric assert(AFI->isThumb2Function()); 8248bcb0991SDimitry Andric Done = rewriteT2FrameIndex(MI, FIOperandNum, FrameReg, Offset, TII, this); 8250b57cec5SDimitry Andric } 8260b57cec5SDimitry Andric if (Done) 8270b57cec5SDimitry Andric return; 8280b57cec5SDimitry Andric 8290b57cec5SDimitry Andric // If we get here, the immediate doesn't fit into the instruction. We folded 8300b57cec5SDimitry Andric // as much as possible above, handle the rest, providing a register that is 8310b57cec5SDimitry Andric // SP+LargeImm. 8328bcb0991SDimitry Andric assert( 8338bcb0991SDimitry Andric (Offset || 8340b57cec5SDimitry Andric (MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrMode4 || 8358bcb0991SDimitry Andric (MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrMode6 || 8368bcb0991SDimitry Andric (MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrModeT2_i7 || 8378bcb0991SDimitry Andric (MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrModeT2_i7s2 || 8388bcb0991SDimitry Andric (MI.getDesc().TSFlags & ARMII::AddrModeMask) == 8398bcb0991SDimitry Andric ARMII::AddrModeT2_i7s4) && 8400b57cec5SDimitry Andric "This code isn't needed if offset already handled!"); 8410b57cec5SDimitry Andric 8420b57cec5SDimitry Andric unsigned ScratchReg = 0; 8430b57cec5SDimitry Andric int PIdx = MI.findFirstPredOperandIdx(); 8440b57cec5SDimitry Andric ARMCC::CondCodes Pred = (PIdx == -1) 8450b57cec5SDimitry Andric ? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm(); 8460b57cec5SDimitry Andric Register PredReg = (PIdx == -1) ? Register() : MI.getOperand(PIdx+1).getReg(); 8478bcb0991SDimitry Andric 8488bcb0991SDimitry Andric const MCInstrDesc &MCID = MI.getDesc(); 8498bcb0991SDimitry Andric const TargetRegisterClass *RegClass = 8508bcb0991SDimitry Andric TII.getRegClass(MCID, FIOperandNum, this, *MI.getParent()->getParent()); 8518bcb0991SDimitry Andric 8528bcb0991SDimitry Andric if (Offset == 0 && 8538bcb0991SDimitry Andric (Register::isVirtualRegister(FrameReg) || RegClass->contains(FrameReg))) 8540b57cec5SDimitry Andric // Must be addrmode4/6. 8550b57cec5SDimitry Andric MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false, false, false); 8560b57cec5SDimitry Andric else { 8578bcb0991SDimitry Andric ScratchReg = MF.getRegInfo().createVirtualRegister(RegClass); 8580b57cec5SDimitry Andric if (!AFI->isThumbFunction()) 8590b57cec5SDimitry Andric emitARMRegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg, 8600b57cec5SDimitry Andric Offset, Pred, PredReg, TII); 8610b57cec5SDimitry Andric else { 8620b57cec5SDimitry Andric assert(AFI->isThumb2Function()); 8630b57cec5SDimitry Andric emitT2RegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg, 8640b57cec5SDimitry Andric Offset, Pred, PredReg, TII); 8650b57cec5SDimitry Andric } 8660b57cec5SDimitry Andric // Update the original instruction to use the scratch register. 8670b57cec5SDimitry Andric MI.getOperand(FIOperandNum).ChangeToRegister(ScratchReg, false, false,true); 8680b57cec5SDimitry Andric } 8690b57cec5SDimitry Andric } 8700b57cec5SDimitry Andric 8710b57cec5SDimitry Andric bool ARMBaseRegisterInfo::shouldCoalesce(MachineInstr *MI, 8720b57cec5SDimitry Andric const TargetRegisterClass *SrcRC, 8730b57cec5SDimitry Andric unsigned SubReg, 8740b57cec5SDimitry Andric const TargetRegisterClass *DstRC, 8750b57cec5SDimitry Andric unsigned DstSubReg, 8760b57cec5SDimitry Andric const TargetRegisterClass *NewRC, 8770b57cec5SDimitry Andric LiveIntervals &LIS) const { 8780b57cec5SDimitry Andric auto MBB = MI->getParent(); 8790b57cec5SDimitry Andric auto MF = MBB->getParent(); 8800b57cec5SDimitry Andric const MachineRegisterInfo &MRI = MF->getRegInfo(); 8810b57cec5SDimitry Andric // If not copying into a sub-register this should be ok because we shouldn't 8820b57cec5SDimitry Andric // need to split the reg. 8830b57cec5SDimitry Andric if (!DstSubReg) 8840b57cec5SDimitry Andric return true; 8850b57cec5SDimitry Andric // Small registers don't frequently cause a problem, so we can coalesce them. 8860b57cec5SDimitry Andric if (getRegSizeInBits(*NewRC) < 256 && getRegSizeInBits(*DstRC) < 256 && 8870b57cec5SDimitry Andric getRegSizeInBits(*SrcRC) < 256) 8880b57cec5SDimitry Andric return true; 8890b57cec5SDimitry Andric 8900b57cec5SDimitry Andric auto NewRCWeight = 8910b57cec5SDimitry Andric MRI.getTargetRegisterInfo()->getRegClassWeight(NewRC); 8920b57cec5SDimitry Andric auto SrcRCWeight = 8930b57cec5SDimitry Andric MRI.getTargetRegisterInfo()->getRegClassWeight(SrcRC); 8940b57cec5SDimitry Andric auto DstRCWeight = 8950b57cec5SDimitry Andric MRI.getTargetRegisterInfo()->getRegClassWeight(DstRC); 8960b57cec5SDimitry Andric // If the source register class is more expensive than the destination, the 8970b57cec5SDimitry Andric // coalescing is probably profitable. 8980b57cec5SDimitry Andric if (SrcRCWeight.RegWeight > NewRCWeight.RegWeight) 8990b57cec5SDimitry Andric return true; 9000b57cec5SDimitry Andric if (DstRCWeight.RegWeight > NewRCWeight.RegWeight) 9010b57cec5SDimitry Andric return true; 9020b57cec5SDimitry Andric 9030b57cec5SDimitry Andric // If the register allocator isn't constrained, we can always allow coalescing 9040b57cec5SDimitry Andric // unfortunately we don't know yet if we will be constrained. 9050b57cec5SDimitry Andric // The goal of this heuristic is to restrict how many expensive registers 9060b57cec5SDimitry Andric // we allow to coalesce in a given basic block. 9070b57cec5SDimitry Andric auto AFI = MF->getInfo<ARMFunctionInfo>(); 9080b57cec5SDimitry Andric auto It = AFI->getCoalescedWeight(MBB); 9090b57cec5SDimitry Andric 9100b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "\tARM::shouldCoalesce - Coalesced Weight: " 9110b57cec5SDimitry Andric << It->second << "\n"); 9120b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "\tARM::shouldCoalesce - Reg Weight: " 9130b57cec5SDimitry Andric << NewRCWeight.RegWeight << "\n"); 9140b57cec5SDimitry Andric 9150b57cec5SDimitry Andric // This number is the largest round number that which meets the criteria: 9160b57cec5SDimitry Andric // (1) addresses PR18825 9170b57cec5SDimitry Andric // (2) generates better code in some test cases (like vldm-shed-a9.ll) 9180b57cec5SDimitry Andric // (3) Doesn't regress any test cases (in-tree, test-suite, and SPEC) 9190b57cec5SDimitry Andric // In practice the SizeMultiplier will only factor in for straight line code 9200b57cec5SDimitry Andric // that uses a lot of NEON vectors, which isn't terribly common. 9210b57cec5SDimitry Andric unsigned SizeMultiplier = MBB->size()/100; 9220b57cec5SDimitry Andric SizeMultiplier = SizeMultiplier ? SizeMultiplier : 1; 9230b57cec5SDimitry Andric if (It->second < NewRCWeight.WeightLimit * SizeMultiplier) { 9240b57cec5SDimitry Andric It->second += NewRCWeight.RegWeight; 9250b57cec5SDimitry Andric return true; 9260b57cec5SDimitry Andric } 9270b57cec5SDimitry Andric return false; 9280b57cec5SDimitry Andric } 929fe6060f1SDimitry Andric 930fe6060f1SDimitry Andric bool ARMBaseRegisterInfo::shouldRewriteCopySrc(const TargetRegisterClass *DefRC, 931fe6060f1SDimitry Andric unsigned DefSubReg, 932fe6060f1SDimitry Andric const TargetRegisterClass *SrcRC, 933fe6060f1SDimitry Andric unsigned SrcSubReg) const { 934fe6060f1SDimitry Andric // We can't extract an SPR from an arbitary DPR (as opposed to a DPR_VFP2). 935fe6060f1SDimitry Andric if (DefRC == &ARM::SPRRegClass && DefSubReg == 0 && 936fe6060f1SDimitry Andric SrcRC == &ARM::DPRRegClass && 937fe6060f1SDimitry Andric (SrcSubReg == ARM::ssub_0 || SrcSubReg == ARM::ssub_1)) 938fe6060f1SDimitry Andric return false; 939fe6060f1SDimitry Andric 940fe6060f1SDimitry Andric return TargetRegisterInfo::shouldRewriteCopySrc(DefRC, DefSubReg, 941fe6060f1SDimitry Andric SrcRC, SrcSubReg); 942fe6060f1SDimitry Andric } 943