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() 580b57cec5SDimitry Andric : ARMGenRegisterInfo(ARM::LR, 0, 0, ARM::PC) {} 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric static unsigned getFramePointerReg(const ARMSubtarget &STI) { 610b57cec5SDimitry Andric return STI.useR7AsFramePointer() ? ARM::R7 : ARM::R11; 620b57cec5SDimitry Andric } 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric const MCPhysReg* 650b57cec5SDimitry Andric ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 660b57cec5SDimitry Andric const ARMSubtarget &STI = MF->getSubtarget<ARMSubtarget>(); 670b57cec5SDimitry Andric bool UseSplitPush = STI.splitFramePushPop(*MF); 680b57cec5SDimitry Andric const MCPhysReg *RegList = 690b57cec5SDimitry Andric STI.isTargetDarwin() 700b57cec5SDimitry Andric ? CSR_iOS_SaveList 710b57cec5SDimitry Andric : (UseSplitPush ? CSR_AAPCS_SplitPush_SaveList : CSR_AAPCS_SaveList); 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric const Function &F = MF->getFunction(); 740b57cec5SDimitry Andric if (F.getCallingConv() == CallingConv::GHC) { 750b57cec5SDimitry Andric // GHC set of callee saved regs is empty as all those regs are 760b57cec5SDimitry Andric // used for passing STG regs around 770b57cec5SDimitry Andric return CSR_NoRegs_SaveList; 780b57cec5SDimitry Andric } else if (F.hasFnAttribute("interrupt")) { 790b57cec5SDimitry Andric if (STI.isMClass()) { 800b57cec5SDimitry Andric // M-class CPUs have hardware which saves the registers needed to allow a 810b57cec5SDimitry Andric // function conforming to the AAPCS to function as a handler. 820b57cec5SDimitry Andric return UseSplitPush ? CSR_AAPCS_SplitPush_SaveList : CSR_AAPCS_SaveList; 830b57cec5SDimitry Andric } else if (F.getFnAttribute("interrupt").getValueAsString() == "FIQ") { 840b57cec5SDimitry Andric // Fast interrupt mode gives the handler a private copy of R8-R14, so less 850b57cec5SDimitry Andric // need to be saved to restore user-mode state. 860b57cec5SDimitry Andric return CSR_FIQ_SaveList; 870b57cec5SDimitry Andric } else { 880b57cec5SDimitry Andric // Generally only R13-R14 (i.e. SP, LR) are automatically preserved by 890b57cec5SDimitry Andric // exception handling. 900b57cec5SDimitry Andric return CSR_GenericInt_SaveList; 910b57cec5SDimitry Andric } 920b57cec5SDimitry Andric } 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric if (STI.getTargetLowering()->supportSwiftError() && 950b57cec5SDimitry Andric F.getAttributes().hasAttrSomewhere(Attribute::SwiftError)) { 960b57cec5SDimitry Andric if (STI.isTargetDarwin()) 970b57cec5SDimitry Andric return CSR_iOS_SwiftError_SaveList; 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric return UseSplitPush ? CSR_AAPCS_SplitPush_SwiftError_SaveList : 1000b57cec5SDimitry Andric CSR_AAPCS_SwiftError_SaveList; 1010b57cec5SDimitry Andric } 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric if (STI.isTargetDarwin() && F.getCallingConv() == CallingConv::CXX_FAST_TLS) 1040b57cec5SDimitry Andric return MF->getInfo<ARMFunctionInfo>()->isSplitCSR() 1050b57cec5SDimitry Andric ? CSR_iOS_CXX_TLS_PE_SaveList 1060b57cec5SDimitry Andric : CSR_iOS_CXX_TLS_SaveList; 1070b57cec5SDimitry Andric return RegList; 1080b57cec5SDimitry Andric } 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric const MCPhysReg *ARMBaseRegisterInfo::getCalleeSavedRegsViaCopy( 1110b57cec5SDimitry Andric const MachineFunction *MF) const { 1120b57cec5SDimitry Andric assert(MF && "Invalid MachineFunction pointer."); 1130b57cec5SDimitry Andric if (MF->getFunction().getCallingConv() == CallingConv::CXX_FAST_TLS && 1140b57cec5SDimitry Andric MF->getInfo<ARMFunctionInfo>()->isSplitCSR()) 1150b57cec5SDimitry Andric return CSR_iOS_CXX_TLS_ViaCopy_SaveList; 1160b57cec5SDimitry Andric return nullptr; 1170b57cec5SDimitry Andric } 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric const uint32_t * 1200b57cec5SDimitry Andric ARMBaseRegisterInfo::getCallPreservedMask(const MachineFunction &MF, 1210b57cec5SDimitry Andric CallingConv::ID CC) const { 1220b57cec5SDimitry Andric const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); 1230b57cec5SDimitry Andric if (CC == CallingConv::GHC) 1240b57cec5SDimitry Andric // This is academic because all GHC calls are (supposed to be) tail calls 1250b57cec5SDimitry Andric return CSR_NoRegs_RegMask; 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric if (STI.getTargetLowering()->supportSwiftError() && 1280b57cec5SDimitry Andric MF.getFunction().getAttributes().hasAttrSomewhere(Attribute::SwiftError)) 1290b57cec5SDimitry Andric return STI.isTargetDarwin() ? CSR_iOS_SwiftError_RegMask 1300b57cec5SDimitry Andric : CSR_AAPCS_SwiftError_RegMask; 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric if (STI.isTargetDarwin() && CC == CallingConv::CXX_FAST_TLS) 1330b57cec5SDimitry Andric return CSR_iOS_CXX_TLS_RegMask; 1340b57cec5SDimitry Andric return STI.isTargetDarwin() ? CSR_iOS_RegMask : CSR_AAPCS_RegMask; 1350b57cec5SDimitry Andric } 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric const uint32_t* 1380b57cec5SDimitry Andric ARMBaseRegisterInfo::getNoPreservedMask() const { 1390b57cec5SDimitry Andric return CSR_NoRegs_RegMask; 1400b57cec5SDimitry Andric } 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric const uint32_t * 1430b57cec5SDimitry Andric ARMBaseRegisterInfo::getTLSCallPreservedMask(const MachineFunction &MF) const { 1440b57cec5SDimitry Andric assert(MF.getSubtarget<ARMSubtarget>().isTargetDarwin() && 1450b57cec5SDimitry Andric "only know about special TLS call on Darwin"); 1460b57cec5SDimitry Andric return CSR_iOS_TLSCall_RegMask; 1470b57cec5SDimitry Andric } 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric const uint32_t * 1500b57cec5SDimitry Andric ARMBaseRegisterInfo::getSjLjDispatchPreservedMask(const MachineFunction &MF) const { 1510b57cec5SDimitry Andric const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); 1520b57cec5SDimitry Andric if (!STI.useSoftFloat() && STI.hasVFP2Base() && !STI.isThumb1Only()) 1530b57cec5SDimitry Andric return CSR_NoRegs_RegMask; 1540b57cec5SDimitry Andric else 1550b57cec5SDimitry Andric return CSR_FPRegs_RegMask; 1560b57cec5SDimitry Andric } 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric const uint32_t * 1590b57cec5SDimitry Andric ARMBaseRegisterInfo::getThisReturnPreservedMask(const MachineFunction &MF, 1600b57cec5SDimitry Andric CallingConv::ID CC) const { 1610b57cec5SDimitry Andric const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); 1620b57cec5SDimitry Andric // This should return a register mask that is the same as that returned by 1630b57cec5SDimitry Andric // getCallPreservedMask but that additionally preserves the register used for 1640b57cec5SDimitry Andric // the first i32 argument (which must also be the register used to return a 1650b57cec5SDimitry Andric // single i32 return value) 1660b57cec5SDimitry Andric // 1670b57cec5SDimitry Andric // In case that the calling convention does not use the same register for 1680b57cec5SDimitry Andric // both or otherwise does not want to enable this optimization, the function 1690b57cec5SDimitry Andric // should return NULL 1700b57cec5SDimitry Andric if (CC == CallingConv::GHC) 1710b57cec5SDimitry Andric // This is academic because all GHC calls are (supposed to be) tail calls 1720b57cec5SDimitry Andric return nullptr; 1730b57cec5SDimitry Andric return STI.isTargetDarwin() ? CSR_iOS_ThisReturn_RegMask 1740b57cec5SDimitry Andric : CSR_AAPCS_ThisReturn_RegMask; 1750b57cec5SDimitry Andric } 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric BitVector ARMBaseRegisterInfo:: 1780b57cec5SDimitry Andric getReservedRegs(const MachineFunction &MF) const { 1790b57cec5SDimitry Andric const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); 1800b57cec5SDimitry Andric const ARMFrameLowering *TFI = getFrameLowering(MF); 1810b57cec5SDimitry Andric 1820b57cec5SDimitry Andric // FIXME: avoid re-calculating this every time. 1830b57cec5SDimitry Andric BitVector Reserved(getNumRegs()); 1840b57cec5SDimitry Andric markSuperRegs(Reserved, ARM::SP); 1850b57cec5SDimitry Andric markSuperRegs(Reserved, ARM::PC); 1860b57cec5SDimitry Andric markSuperRegs(Reserved, ARM::FPSCR); 1870b57cec5SDimitry Andric markSuperRegs(Reserved, ARM::APSR_NZCV); 1880b57cec5SDimitry Andric if (TFI->hasFP(MF)) 1890b57cec5SDimitry Andric markSuperRegs(Reserved, getFramePointerReg(STI)); 1900b57cec5SDimitry Andric if (hasBasePointer(MF)) 1910b57cec5SDimitry Andric markSuperRegs(Reserved, BasePtr); 1920b57cec5SDimitry Andric // Some targets reserve R9. 1930b57cec5SDimitry Andric if (STI.isR9Reserved()) 1940b57cec5SDimitry Andric markSuperRegs(Reserved, ARM::R9); 1950b57cec5SDimitry Andric // Reserve D16-D31 if the subtarget doesn't support them. 1960b57cec5SDimitry Andric if (!STI.hasD32()) { 1970b57cec5SDimitry Andric static_assert(ARM::D31 == ARM::D16 + 15, "Register list not consecutive!"); 1980b57cec5SDimitry Andric for (unsigned R = 0; R < 16; ++R) 1990b57cec5SDimitry Andric markSuperRegs(Reserved, ARM::D16 + R); 2000b57cec5SDimitry Andric } 2010b57cec5SDimitry Andric const TargetRegisterClass &RC = ARM::GPRPairRegClass; 2020b57cec5SDimitry Andric for (unsigned Reg : RC) 2030b57cec5SDimitry Andric for (MCSubRegIterator SI(Reg, this); SI.isValid(); ++SI) 2040b57cec5SDimitry Andric if (Reserved.test(*SI)) 2050b57cec5SDimitry Andric markSuperRegs(Reserved, Reg); 2060b57cec5SDimitry Andric // For v8.1m architecture 2070b57cec5SDimitry Andric markSuperRegs(Reserved, ARM::ZR); 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric assert(checkAllSuperRegsMarked(Reserved)); 2100b57cec5SDimitry Andric return Reserved; 2110b57cec5SDimitry Andric } 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric bool ARMBaseRegisterInfo:: 2140b57cec5SDimitry Andric isAsmClobberable(const MachineFunction &MF, unsigned PhysReg) const { 2150b57cec5SDimitry Andric return !getReservedRegs(MF).test(PhysReg); 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric const TargetRegisterClass * 2190b57cec5SDimitry Andric ARMBaseRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC, 2200b57cec5SDimitry Andric const MachineFunction &) const { 2210b57cec5SDimitry Andric const TargetRegisterClass *Super = RC; 2220b57cec5SDimitry Andric TargetRegisterClass::sc_iterator I = RC->getSuperClasses(); 2230b57cec5SDimitry Andric do { 2240b57cec5SDimitry Andric switch (Super->getID()) { 2250b57cec5SDimitry Andric case ARM::GPRRegClassID: 2260b57cec5SDimitry Andric case ARM::SPRRegClassID: 2270b57cec5SDimitry Andric case ARM::DPRRegClassID: 2280b57cec5SDimitry Andric case ARM::QPRRegClassID: 2290b57cec5SDimitry Andric case ARM::QQPRRegClassID: 2300b57cec5SDimitry Andric case ARM::QQQQPRRegClassID: 2310b57cec5SDimitry Andric case ARM::GPRPairRegClassID: 2320b57cec5SDimitry Andric return Super; 2330b57cec5SDimitry Andric } 2340b57cec5SDimitry Andric Super = *I++; 2350b57cec5SDimitry Andric } while (Super); 2360b57cec5SDimitry Andric return RC; 2370b57cec5SDimitry Andric } 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric const TargetRegisterClass * 2400b57cec5SDimitry Andric ARMBaseRegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind) 2410b57cec5SDimitry Andric const { 2420b57cec5SDimitry Andric return &ARM::GPRRegClass; 2430b57cec5SDimitry Andric } 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andric const TargetRegisterClass * 2460b57cec5SDimitry Andric ARMBaseRegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const { 2470b57cec5SDimitry Andric if (RC == &ARM::CCRRegClass) 2480b57cec5SDimitry Andric return &ARM::rGPRRegClass; // Can't copy CCR registers. 2490b57cec5SDimitry Andric return RC; 2500b57cec5SDimitry Andric } 2510b57cec5SDimitry Andric 2520b57cec5SDimitry Andric unsigned 2530b57cec5SDimitry Andric ARMBaseRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC, 2540b57cec5SDimitry Andric MachineFunction &MF) const { 2550b57cec5SDimitry Andric const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); 2560b57cec5SDimitry Andric const ARMFrameLowering *TFI = getFrameLowering(MF); 2570b57cec5SDimitry Andric 2580b57cec5SDimitry Andric switch (RC->getID()) { 2590b57cec5SDimitry Andric default: 2600b57cec5SDimitry Andric return 0; 2610b57cec5SDimitry Andric case ARM::tGPRRegClassID: { 2620b57cec5SDimitry Andric // hasFP ends up calling getMaxCallFrameComputed() which may not be 2630b57cec5SDimitry Andric // available when getPressureLimit() is called as part of 2640b57cec5SDimitry Andric // ScheduleDAGRRList. 2650b57cec5SDimitry Andric bool HasFP = MF.getFrameInfo().isMaxCallFrameSizeComputed() 2660b57cec5SDimitry Andric ? TFI->hasFP(MF) : true; 2670b57cec5SDimitry Andric return 5 - HasFP; 2680b57cec5SDimitry Andric } 2690b57cec5SDimitry Andric case ARM::GPRRegClassID: { 2700b57cec5SDimitry Andric bool HasFP = MF.getFrameInfo().isMaxCallFrameSizeComputed() 2710b57cec5SDimitry Andric ? TFI->hasFP(MF) : true; 2720b57cec5SDimitry Andric return 10 - HasFP - (STI.isR9Reserved() ? 1 : 0); 2730b57cec5SDimitry Andric } 2740b57cec5SDimitry Andric case ARM::SPRRegClassID: // Currently not used as 'rep' register class. 2750b57cec5SDimitry Andric case ARM::DPRRegClassID: 2760b57cec5SDimitry Andric return 32 - 10; 2770b57cec5SDimitry Andric } 2780b57cec5SDimitry Andric } 2790b57cec5SDimitry Andric 2800b57cec5SDimitry Andric // Get the other register in a GPRPair. 2810b57cec5SDimitry Andric static unsigned getPairedGPR(unsigned Reg, bool Odd, const MCRegisterInfo *RI) { 2820b57cec5SDimitry Andric for (MCSuperRegIterator Supers(Reg, RI); Supers.isValid(); ++Supers) 2830b57cec5SDimitry Andric if (ARM::GPRPairRegClass.contains(*Supers)) 2840b57cec5SDimitry Andric return RI->getSubReg(*Supers, Odd ? ARM::gsub_1 : ARM::gsub_0); 2850b57cec5SDimitry Andric return 0; 2860b57cec5SDimitry Andric } 2870b57cec5SDimitry Andric 2880b57cec5SDimitry Andric // Resolve the RegPairEven / RegPairOdd register allocator hints. 2890b57cec5SDimitry Andric bool 2900b57cec5SDimitry Andric ARMBaseRegisterInfo::getRegAllocationHints(unsigned VirtReg, 2910b57cec5SDimitry Andric ArrayRef<MCPhysReg> Order, 2920b57cec5SDimitry Andric SmallVectorImpl<MCPhysReg> &Hints, 2930b57cec5SDimitry Andric const MachineFunction &MF, 2940b57cec5SDimitry Andric const VirtRegMap *VRM, 2950b57cec5SDimitry Andric const LiveRegMatrix *Matrix) const { 2960b57cec5SDimitry Andric const MachineRegisterInfo &MRI = MF.getRegInfo(); 2970b57cec5SDimitry Andric std::pair<unsigned, unsigned> Hint = MRI.getRegAllocationHint(VirtReg); 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric unsigned Odd; 3000b57cec5SDimitry Andric switch (Hint.first) { 3010b57cec5SDimitry Andric case ARMRI::RegPairEven: 3020b57cec5SDimitry Andric Odd = 0; 3030b57cec5SDimitry Andric break; 3040b57cec5SDimitry Andric case ARMRI::RegPairOdd: 3050b57cec5SDimitry Andric Odd = 1; 3060b57cec5SDimitry Andric break; 3070b57cec5SDimitry Andric default: 3080b57cec5SDimitry Andric TargetRegisterInfo::getRegAllocationHints(VirtReg, Order, Hints, MF, VRM); 3090b57cec5SDimitry Andric return false; 3100b57cec5SDimitry Andric } 3110b57cec5SDimitry Andric 3120b57cec5SDimitry Andric // This register should preferably be even (Odd == 0) or odd (Odd == 1). 3130b57cec5SDimitry Andric // Check if the other part of the pair has already been assigned, and provide 3140b57cec5SDimitry Andric // the paired register as the first hint. 3150b57cec5SDimitry Andric unsigned Paired = Hint.second; 3160b57cec5SDimitry Andric if (Paired == 0) 3170b57cec5SDimitry Andric return false; 3180b57cec5SDimitry Andric 3190b57cec5SDimitry Andric unsigned PairedPhys = 0; 3200b57cec5SDimitry Andric if (TargetRegisterInfo::isPhysicalRegister(Paired)) { 3210b57cec5SDimitry Andric PairedPhys = Paired; 3220b57cec5SDimitry Andric } else if (VRM && VRM->hasPhys(Paired)) { 3230b57cec5SDimitry Andric PairedPhys = getPairedGPR(VRM->getPhys(Paired), Odd, this); 3240b57cec5SDimitry Andric } 3250b57cec5SDimitry Andric 3260b57cec5SDimitry Andric // First prefer the paired physreg. 3270b57cec5SDimitry Andric if (PairedPhys && is_contained(Order, PairedPhys)) 3280b57cec5SDimitry Andric Hints.push_back(PairedPhys); 3290b57cec5SDimitry Andric 3300b57cec5SDimitry Andric // Then prefer even or odd registers. 3310b57cec5SDimitry Andric for (unsigned Reg : Order) { 3320b57cec5SDimitry Andric if (Reg == PairedPhys || (getEncodingValue(Reg) & 1) != Odd) 3330b57cec5SDimitry Andric continue; 3340b57cec5SDimitry Andric // Don't provide hints that are paired to a reserved register. 3350b57cec5SDimitry Andric unsigned Paired = getPairedGPR(Reg, !Odd, this); 3360b57cec5SDimitry Andric if (!Paired || MRI.isReserved(Paired)) 3370b57cec5SDimitry Andric continue; 3380b57cec5SDimitry Andric Hints.push_back(Reg); 3390b57cec5SDimitry Andric } 3400b57cec5SDimitry Andric return false; 3410b57cec5SDimitry Andric } 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andric void 3440b57cec5SDimitry Andric ARMBaseRegisterInfo::updateRegAllocHint(unsigned Reg, unsigned NewReg, 3450b57cec5SDimitry Andric MachineFunction &MF) const { 3460b57cec5SDimitry Andric MachineRegisterInfo *MRI = &MF.getRegInfo(); 3470b57cec5SDimitry Andric std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(Reg); 3480b57cec5SDimitry Andric if ((Hint.first == (unsigned)ARMRI::RegPairOdd || 3490b57cec5SDimitry Andric Hint.first == (unsigned)ARMRI::RegPairEven) && 3500b57cec5SDimitry Andric TargetRegisterInfo::isVirtualRegister(Hint.second)) { 3510b57cec5SDimitry Andric // If 'Reg' is one of the even / odd register pair and it's now changed 3520b57cec5SDimitry Andric // (e.g. coalesced) into a different register. The other register of the 3530b57cec5SDimitry Andric // pair allocation hint must be updated to reflect the relationship 3540b57cec5SDimitry Andric // change. 3550b57cec5SDimitry Andric unsigned OtherReg = Hint.second; 3560b57cec5SDimitry Andric Hint = MRI->getRegAllocationHint(OtherReg); 3570b57cec5SDimitry Andric // Make sure the pair has not already divorced. 3580b57cec5SDimitry Andric if (Hint.second == Reg) { 3590b57cec5SDimitry Andric MRI->setRegAllocationHint(OtherReg, Hint.first, NewReg); 3600b57cec5SDimitry Andric if (TargetRegisterInfo::isVirtualRegister(NewReg)) 3610b57cec5SDimitry Andric MRI->setRegAllocationHint(NewReg, 3620b57cec5SDimitry Andric Hint.first == (unsigned)ARMRI::RegPairOdd ? ARMRI::RegPairEven 3630b57cec5SDimitry Andric : ARMRI::RegPairOdd, OtherReg); 3640b57cec5SDimitry Andric } 3650b57cec5SDimitry Andric } 3660b57cec5SDimitry Andric } 3670b57cec5SDimitry Andric 3680b57cec5SDimitry Andric bool ARMBaseRegisterInfo::hasBasePointer(const MachineFunction &MF) const { 3690b57cec5SDimitry Andric const MachineFrameInfo &MFI = MF.getFrameInfo(); 3700b57cec5SDimitry Andric const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 3710b57cec5SDimitry Andric const ARMFrameLowering *TFI = getFrameLowering(MF); 3720b57cec5SDimitry Andric 3730b57cec5SDimitry Andric // If we have stack realignment and VLAs, we have no pointer to use to 3740b57cec5SDimitry Andric // access the stack. If we have stack realignment, and a large call frame, 3750b57cec5SDimitry Andric // we have no place to allocate the emergency spill slot. 3760b57cec5SDimitry Andric if (needsStackRealignment(MF) && !TFI->hasReservedCallFrame(MF)) 3770b57cec5SDimitry Andric return true; 3780b57cec5SDimitry Andric 3790b57cec5SDimitry Andric // Thumb has trouble with negative offsets from the FP. Thumb2 has a limited 3800b57cec5SDimitry Andric // negative range for ldr/str (255), and thumb1 is positive offsets only. 3810b57cec5SDimitry Andric // 3820b57cec5SDimitry Andric // It's going to be better to use the SP or Base Pointer instead. When there 3830b57cec5SDimitry Andric // are variable sized objects, we can't reference off of the SP, so we 3840b57cec5SDimitry Andric // reserve a Base Pointer. 3850b57cec5SDimitry Andric // 3860b57cec5SDimitry Andric // For Thumb2, estimate whether a negative offset from the frame pointer 3870b57cec5SDimitry Andric // will be sufficient to reach the whole stack frame. If a function has a 3880b57cec5SDimitry Andric // smallish frame, it's less likely to have lots of spills and callee saved 3890b57cec5SDimitry Andric // space, so it's all more likely to be within range of the frame pointer. 3900b57cec5SDimitry Andric // If it's wrong, the scavenger will still enable access to work, it just 3910b57cec5SDimitry Andric // won't be optimal. (We should always be able to reach the emergency 3920b57cec5SDimitry Andric // spill slot from the frame pointer.) 3930b57cec5SDimitry Andric if (AFI->isThumb2Function() && MFI.hasVarSizedObjects() && 3940b57cec5SDimitry Andric MFI.getLocalFrameSize() >= 128) 3950b57cec5SDimitry Andric return true; 3960b57cec5SDimitry Andric // For Thumb1, if sp moves, nothing is in range, so force a base pointer. 3970b57cec5SDimitry Andric // This is necessary for correctness in cases where we need an emergency 3980b57cec5SDimitry Andric // spill slot. (In Thumb1, we can't use a negative offset from the frame 3990b57cec5SDimitry Andric // pointer.) 4000b57cec5SDimitry Andric if (AFI->isThumb1OnlyFunction() && !TFI->hasReservedCallFrame(MF)) 4010b57cec5SDimitry Andric return true; 4020b57cec5SDimitry Andric return false; 4030b57cec5SDimitry Andric } 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric bool ARMBaseRegisterInfo::canRealignStack(const MachineFunction &MF) const { 4060b57cec5SDimitry Andric const MachineRegisterInfo *MRI = &MF.getRegInfo(); 4070b57cec5SDimitry Andric const ARMFrameLowering *TFI = getFrameLowering(MF); 4080b57cec5SDimitry Andric // We can't realign the stack if: 4090b57cec5SDimitry Andric // 1. Dynamic stack realignment is explicitly disabled, 4100b57cec5SDimitry Andric // 2. There are VLAs in the function and the base pointer is disabled. 4110b57cec5SDimitry Andric if (!TargetRegisterInfo::canRealignStack(MF)) 4120b57cec5SDimitry Andric return false; 4130b57cec5SDimitry Andric // Stack realignment requires a frame pointer. If we already started 4140b57cec5SDimitry Andric // register allocation with frame pointer elimination, it is too late now. 4150b57cec5SDimitry Andric if (!MRI->canReserveReg(getFramePointerReg(MF.getSubtarget<ARMSubtarget>()))) 4160b57cec5SDimitry Andric return false; 4170b57cec5SDimitry Andric // We may also need a base pointer if there are dynamic allocas or stack 4180b57cec5SDimitry Andric // pointer adjustments around calls. 4190b57cec5SDimitry Andric if (TFI->hasReservedCallFrame(MF)) 4200b57cec5SDimitry Andric return true; 4210b57cec5SDimitry Andric // A base pointer is required and allowed. Check that it isn't too late to 4220b57cec5SDimitry Andric // reserve it. 4230b57cec5SDimitry Andric return MRI->canReserveReg(BasePtr); 4240b57cec5SDimitry Andric } 4250b57cec5SDimitry Andric 4260b57cec5SDimitry Andric bool ARMBaseRegisterInfo:: 4270b57cec5SDimitry Andric cannotEliminateFrame(const MachineFunction &MF) const { 4280b57cec5SDimitry Andric const MachineFrameInfo &MFI = MF.getFrameInfo(); 4290b57cec5SDimitry Andric if (MF.getTarget().Options.DisableFramePointerElim(MF) && MFI.adjustsStack()) 4300b57cec5SDimitry Andric return true; 4310b57cec5SDimitry Andric return MFI.hasVarSizedObjects() || MFI.isFrameAddressTaken() 4320b57cec5SDimitry Andric || needsStackRealignment(MF); 4330b57cec5SDimitry Andric } 4340b57cec5SDimitry Andric 4350b57cec5SDimitry Andric Register 4360b57cec5SDimitry Andric ARMBaseRegisterInfo::getFrameRegister(const MachineFunction &MF) const { 4370b57cec5SDimitry Andric const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); 4380b57cec5SDimitry Andric const ARMFrameLowering *TFI = getFrameLowering(MF); 4390b57cec5SDimitry Andric 4400b57cec5SDimitry Andric if (TFI->hasFP(MF)) 4410b57cec5SDimitry Andric return getFramePointerReg(STI); 4420b57cec5SDimitry Andric return ARM::SP; 4430b57cec5SDimitry Andric } 4440b57cec5SDimitry Andric 4450b57cec5SDimitry Andric /// emitLoadConstPool - Emits a load from constpool to materialize the 4460b57cec5SDimitry Andric /// specified immediate. 4470b57cec5SDimitry Andric void ARMBaseRegisterInfo::emitLoadConstPool( 4480b57cec5SDimitry Andric MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 4490b57cec5SDimitry Andric const DebugLoc &dl, unsigned DestReg, unsigned SubIdx, int Val, 4500b57cec5SDimitry Andric ARMCC::CondCodes Pred, unsigned PredReg, unsigned MIFlags) const { 4510b57cec5SDimitry Andric MachineFunction &MF = *MBB.getParent(); 4520b57cec5SDimitry Andric const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); 4530b57cec5SDimitry Andric MachineConstantPool *ConstantPool = MF.getConstantPool(); 4540b57cec5SDimitry Andric const Constant *C = 4550b57cec5SDimitry Andric ConstantInt::get(Type::getInt32Ty(MF.getFunction().getContext()), Val); 4560b57cec5SDimitry Andric unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4); 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andric BuildMI(MBB, MBBI, dl, TII.get(ARM::LDRcp)) 4590b57cec5SDimitry Andric .addReg(DestReg, getDefRegState(true), SubIdx) 4600b57cec5SDimitry Andric .addConstantPoolIndex(Idx) 4610b57cec5SDimitry Andric .addImm(0) 4620b57cec5SDimitry Andric .add(predOps(Pred, PredReg)) 4630b57cec5SDimitry Andric .setMIFlags(MIFlags); 4640b57cec5SDimitry Andric } 4650b57cec5SDimitry Andric 4660b57cec5SDimitry Andric bool ARMBaseRegisterInfo:: 4670b57cec5SDimitry Andric requiresRegisterScavenging(const MachineFunction &MF) const { 4680b57cec5SDimitry Andric return true; 4690b57cec5SDimitry Andric } 4700b57cec5SDimitry Andric 4710b57cec5SDimitry Andric bool ARMBaseRegisterInfo:: 4720b57cec5SDimitry Andric trackLivenessAfterRegAlloc(const MachineFunction &MF) const { 4730b57cec5SDimitry Andric return true; 4740b57cec5SDimitry Andric } 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andric bool ARMBaseRegisterInfo:: 4770b57cec5SDimitry Andric requiresFrameIndexScavenging(const MachineFunction &MF) const { 4780b57cec5SDimitry Andric return true; 4790b57cec5SDimitry Andric } 4800b57cec5SDimitry Andric 4810b57cec5SDimitry Andric bool ARMBaseRegisterInfo:: 4820b57cec5SDimitry Andric requiresVirtualBaseRegisters(const MachineFunction &MF) const { 4830b57cec5SDimitry Andric return true; 4840b57cec5SDimitry Andric } 4850b57cec5SDimitry Andric 4860b57cec5SDimitry Andric int64_t ARMBaseRegisterInfo:: 4870b57cec5SDimitry Andric getFrameIndexInstrOffset(const MachineInstr *MI, int Idx) const { 4880b57cec5SDimitry Andric const MCInstrDesc &Desc = MI->getDesc(); 4890b57cec5SDimitry Andric unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 4900b57cec5SDimitry Andric int64_t InstrOffs = 0; 4910b57cec5SDimitry Andric int Scale = 1; 4920b57cec5SDimitry Andric unsigned ImmIdx = 0; 4930b57cec5SDimitry Andric switch (AddrMode) { 4940b57cec5SDimitry Andric case ARMII::AddrModeT2_i8: 4950b57cec5SDimitry Andric case ARMII::AddrModeT2_i12: 4960b57cec5SDimitry Andric case ARMII::AddrMode_i12: 4970b57cec5SDimitry Andric InstrOffs = MI->getOperand(Idx+1).getImm(); 4980b57cec5SDimitry Andric Scale = 1; 4990b57cec5SDimitry Andric break; 5000b57cec5SDimitry Andric case ARMII::AddrMode5: { 5010b57cec5SDimitry Andric // VFP address mode. 5020b57cec5SDimitry Andric const MachineOperand &OffOp = MI->getOperand(Idx+1); 5030b57cec5SDimitry Andric InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm()); 5040b57cec5SDimitry Andric if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub) 5050b57cec5SDimitry Andric InstrOffs = -InstrOffs; 5060b57cec5SDimitry Andric Scale = 4; 5070b57cec5SDimitry Andric break; 5080b57cec5SDimitry Andric } 5090b57cec5SDimitry Andric case ARMII::AddrMode2: 5100b57cec5SDimitry Andric ImmIdx = Idx+2; 5110b57cec5SDimitry Andric InstrOffs = ARM_AM::getAM2Offset(MI->getOperand(ImmIdx).getImm()); 5120b57cec5SDimitry Andric if (ARM_AM::getAM2Op(MI->getOperand(ImmIdx).getImm()) == ARM_AM::sub) 5130b57cec5SDimitry Andric InstrOffs = -InstrOffs; 5140b57cec5SDimitry Andric break; 5150b57cec5SDimitry Andric case ARMII::AddrMode3: 5160b57cec5SDimitry Andric ImmIdx = Idx+2; 5170b57cec5SDimitry Andric InstrOffs = ARM_AM::getAM3Offset(MI->getOperand(ImmIdx).getImm()); 5180b57cec5SDimitry Andric if (ARM_AM::getAM3Op(MI->getOperand(ImmIdx).getImm()) == ARM_AM::sub) 5190b57cec5SDimitry Andric InstrOffs = -InstrOffs; 5200b57cec5SDimitry Andric break; 5210b57cec5SDimitry Andric case ARMII::AddrModeT1_s: 5220b57cec5SDimitry Andric ImmIdx = Idx+1; 5230b57cec5SDimitry Andric InstrOffs = MI->getOperand(ImmIdx).getImm(); 5240b57cec5SDimitry Andric Scale = 4; 5250b57cec5SDimitry Andric break; 5260b57cec5SDimitry Andric default: 5270b57cec5SDimitry Andric llvm_unreachable("Unsupported addressing mode!"); 5280b57cec5SDimitry Andric } 5290b57cec5SDimitry Andric 5300b57cec5SDimitry Andric return InstrOffs * Scale; 5310b57cec5SDimitry Andric } 5320b57cec5SDimitry Andric 5330b57cec5SDimitry Andric /// needsFrameBaseReg - Returns true if the instruction's frame index 5340b57cec5SDimitry Andric /// reference would be better served by a base register other than FP 5350b57cec5SDimitry Andric /// or SP. Used by LocalStackFrameAllocation to determine which frame index 5360b57cec5SDimitry Andric /// references it should create new base registers for. 5370b57cec5SDimitry Andric bool ARMBaseRegisterInfo:: 5380b57cec5SDimitry Andric needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const { 5390b57cec5SDimitry Andric for (unsigned i = 0; !MI->getOperand(i).isFI(); ++i) { 5400b57cec5SDimitry Andric assert(i < MI->getNumOperands() &&"Instr doesn't have FrameIndex operand!"); 5410b57cec5SDimitry Andric } 5420b57cec5SDimitry Andric 5430b57cec5SDimitry Andric // It's the load/store FI references that cause issues, as it can be difficult 5440b57cec5SDimitry Andric // to materialize the offset if it won't fit in the literal field. Estimate 5450b57cec5SDimitry Andric // based on the size of the local frame and some conservative assumptions 5460b57cec5SDimitry Andric // about the rest of the stack frame (note, this is pre-regalloc, so 5470b57cec5SDimitry Andric // we don't know everything for certain yet) whether this offset is likely 5480b57cec5SDimitry Andric // to be out of range of the immediate. Return true if so. 5490b57cec5SDimitry Andric 5500b57cec5SDimitry Andric // We only generate virtual base registers for loads and stores, so 5510b57cec5SDimitry Andric // return false for everything else. 5520b57cec5SDimitry Andric unsigned Opc = MI->getOpcode(); 5530b57cec5SDimitry Andric switch (Opc) { 5540b57cec5SDimitry Andric case ARM::LDRi12: case ARM::LDRH: case ARM::LDRBi12: 5550b57cec5SDimitry Andric case ARM::STRi12: case ARM::STRH: case ARM::STRBi12: 5560b57cec5SDimitry Andric case ARM::t2LDRi12: case ARM::t2LDRi8: 5570b57cec5SDimitry Andric case ARM::t2STRi12: case ARM::t2STRi8: 5580b57cec5SDimitry Andric case ARM::VLDRS: case ARM::VLDRD: 5590b57cec5SDimitry Andric case ARM::VSTRS: case ARM::VSTRD: 5600b57cec5SDimitry Andric case ARM::tSTRspi: case ARM::tLDRspi: 5610b57cec5SDimitry Andric break; 5620b57cec5SDimitry Andric default: 5630b57cec5SDimitry Andric return false; 5640b57cec5SDimitry Andric } 5650b57cec5SDimitry Andric 5660b57cec5SDimitry Andric // Without a virtual base register, if the function has variable sized 5670b57cec5SDimitry Andric // objects, all fixed-size local references will be via the frame pointer, 5680b57cec5SDimitry Andric // Approximate the offset and see if it's legal for the instruction. 5690b57cec5SDimitry Andric // Note that the incoming offset is based on the SP value at function entry, 5700b57cec5SDimitry Andric // so it'll be negative. 5710b57cec5SDimitry Andric MachineFunction &MF = *MI->getParent()->getParent(); 5720b57cec5SDimitry Andric const ARMFrameLowering *TFI = getFrameLowering(MF); 5730b57cec5SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo(); 5740b57cec5SDimitry Andric ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 5750b57cec5SDimitry Andric 5760b57cec5SDimitry Andric // Estimate an offset from the frame pointer. 5770b57cec5SDimitry Andric // Conservatively assume all callee-saved registers get pushed. R4-R6 5780b57cec5SDimitry Andric // will be earlier than the FP, so we ignore those. 5790b57cec5SDimitry Andric // R7, LR 5800b57cec5SDimitry Andric int64_t FPOffset = Offset - 8; 5810b57cec5SDimitry Andric // ARM and Thumb2 functions also need to consider R8-R11 and D8-D15 5820b57cec5SDimitry Andric if (!AFI->isThumbFunction() || !AFI->isThumb1OnlyFunction()) 5830b57cec5SDimitry Andric FPOffset -= 80; 5840b57cec5SDimitry Andric // Estimate an offset from the stack pointer. 5850b57cec5SDimitry Andric // The incoming offset is relating to the SP at the start of the function, 5860b57cec5SDimitry Andric // but when we access the local it'll be relative to the SP after local 5870b57cec5SDimitry Andric // allocation, so adjust our SP-relative offset by that allocation size. 5880b57cec5SDimitry Andric Offset += MFI.getLocalFrameSize(); 5890b57cec5SDimitry Andric // Assume that we'll have at least some spill slots allocated. 5900b57cec5SDimitry Andric // FIXME: This is a total SWAG number. We should run some statistics 5910b57cec5SDimitry Andric // and pick a real one. 5920b57cec5SDimitry Andric Offset += 128; // 128 bytes of spill slots 5930b57cec5SDimitry Andric 5940b57cec5SDimitry Andric // If there's a frame pointer and the addressing mode allows it, try using it. 5950b57cec5SDimitry Andric // The FP is only available if there is no dynamic realignment. We 5960b57cec5SDimitry Andric // don't know for sure yet whether we'll need that, so we guess based 5970b57cec5SDimitry Andric // on whether there are any local variables that would trigger it. 5980b57cec5SDimitry Andric unsigned StackAlign = TFI->getStackAlignment(); 5990b57cec5SDimitry Andric if (TFI->hasFP(MF) && 6000b57cec5SDimitry Andric !((MFI.getLocalFrameMaxAlign() > StackAlign) && canRealignStack(MF))) { 6010b57cec5SDimitry Andric if (isFrameOffsetLegal(MI, getFrameRegister(MF), FPOffset)) 6020b57cec5SDimitry Andric return false; 6030b57cec5SDimitry Andric } 6040b57cec5SDimitry Andric // If we can reference via the stack pointer, try that. 6050b57cec5SDimitry Andric // FIXME: This (and the code that resolves the references) can be improved 6060b57cec5SDimitry Andric // to only disallow SP relative references in the live range of 6070b57cec5SDimitry Andric // the VLA(s). In practice, it's unclear how much difference that 6080b57cec5SDimitry Andric // would make, but it may be worth doing. 6090b57cec5SDimitry Andric if (!MFI.hasVarSizedObjects() && isFrameOffsetLegal(MI, ARM::SP, Offset)) 6100b57cec5SDimitry Andric return false; 6110b57cec5SDimitry Andric 6120b57cec5SDimitry Andric // The offset likely isn't legal, we want to allocate a virtual base register. 6130b57cec5SDimitry Andric return true; 6140b57cec5SDimitry Andric } 6150b57cec5SDimitry Andric 6160b57cec5SDimitry Andric /// materializeFrameBaseRegister - Insert defining instruction(s) for BaseReg to 6170b57cec5SDimitry Andric /// be a pointer to FrameIdx at the beginning of the basic block. 6180b57cec5SDimitry Andric void ARMBaseRegisterInfo:: 6190b57cec5SDimitry Andric materializeFrameBaseRegister(MachineBasicBlock *MBB, 6200b57cec5SDimitry Andric unsigned BaseReg, int FrameIdx, 6210b57cec5SDimitry Andric int64_t Offset) const { 6220b57cec5SDimitry Andric ARMFunctionInfo *AFI = MBB->getParent()->getInfo<ARMFunctionInfo>(); 6230b57cec5SDimitry Andric unsigned ADDriOpc = !AFI->isThumbFunction() ? ARM::ADDri : 6240b57cec5SDimitry Andric (AFI->isThumb1OnlyFunction() ? ARM::tADDframe : ARM::t2ADDri); 6250b57cec5SDimitry Andric 6260b57cec5SDimitry Andric MachineBasicBlock::iterator Ins = MBB->begin(); 6270b57cec5SDimitry Andric DebugLoc DL; // Defaults to "unknown" 6280b57cec5SDimitry Andric if (Ins != MBB->end()) 6290b57cec5SDimitry Andric DL = Ins->getDebugLoc(); 6300b57cec5SDimitry Andric 6310b57cec5SDimitry Andric const MachineFunction &MF = *MBB->getParent(); 6320b57cec5SDimitry Andric MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo(); 6330b57cec5SDimitry Andric const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); 6340b57cec5SDimitry Andric const MCInstrDesc &MCID = TII.get(ADDriOpc); 6350b57cec5SDimitry Andric MRI.constrainRegClass(BaseReg, TII.getRegClass(MCID, 0, this, MF)); 6360b57cec5SDimitry Andric 6370b57cec5SDimitry Andric MachineInstrBuilder MIB = BuildMI(*MBB, Ins, DL, MCID, BaseReg) 6380b57cec5SDimitry Andric .addFrameIndex(FrameIdx).addImm(Offset); 6390b57cec5SDimitry Andric 6400b57cec5SDimitry Andric if (!AFI->isThumb1OnlyFunction()) 6410b57cec5SDimitry Andric MIB.add(predOps(ARMCC::AL)).add(condCodeOp()); 6420b57cec5SDimitry Andric } 6430b57cec5SDimitry Andric 6440b57cec5SDimitry Andric void ARMBaseRegisterInfo::resolveFrameIndex(MachineInstr &MI, unsigned BaseReg, 6450b57cec5SDimitry Andric int64_t Offset) const { 6460b57cec5SDimitry Andric MachineBasicBlock &MBB = *MI.getParent(); 6470b57cec5SDimitry Andric MachineFunction &MF = *MBB.getParent(); 6480b57cec5SDimitry Andric const ARMBaseInstrInfo &TII = 6490b57cec5SDimitry Andric *static_cast<const ARMBaseInstrInfo *>(MF.getSubtarget().getInstrInfo()); 6500b57cec5SDimitry Andric ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 6510b57cec5SDimitry Andric int Off = Offset; // ARM doesn't need the general 64-bit offsets 6520b57cec5SDimitry Andric unsigned i = 0; 6530b57cec5SDimitry Andric 6540b57cec5SDimitry Andric assert(!AFI->isThumb1OnlyFunction() && 6550b57cec5SDimitry Andric "This resolveFrameIndex does not support Thumb1!"); 6560b57cec5SDimitry Andric 6570b57cec5SDimitry Andric while (!MI.getOperand(i).isFI()) { 6580b57cec5SDimitry Andric ++i; 6590b57cec5SDimitry Andric assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 6600b57cec5SDimitry Andric } 6610b57cec5SDimitry Andric bool Done = false; 6620b57cec5SDimitry Andric if (!AFI->isThumbFunction()) 6630b57cec5SDimitry Andric Done = rewriteARMFrameIndex(MI, i, BaseReg, Off, TII); 6640b57cec5SDimitry Andric else { 6650b57cec5SDimitry Andric assert(AFI->isThumb2Function()); 6660b57cec5SDimitry Andric Done = rewriteT2FrameIndex(MI, i, BaseReg, Off, TII); 6670b57cec5SDimitry Andric } 6680b57cec5SDimitry Andric assert(Done && "Unable to resolve frame index!"); 6690b57cec5SDimitry Andric (void)Done; 6700b57cec5SDimitry Andric } 6710b57cec5SDimitry Andric 6720b57cec5SDimitry Andric bool ARMBaseRegisterInfo::isFrameOffsetLegal(const MachineInstr *MI, unsigned BaseReg, 6730b57cec5SDimitry Andric int64_t Offset) const { 6740b57cec5SDimitry Andric const MCInstrDesc &Desc = MI->getDesc(); 6750b57cec5SDimitry Andric unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 6760b57cec5SDimitry Andric unsigned i = 0; 6770b57cec5SDimitry Andric for (; !MI->getOperand(i).isFI(); ++i) 6780b57cec5SDimitry Andric assert(i+1 < MI->getNumOperands() && "Instr doesn't have FrameIndex operand!"); 6790b57cec5SDimitry Andric 6800b57cec5SDimitry Andric // AddrMode4 and AddrMode6 cannot handle any offset. 6810b57cec5SDimitry Andric if (AddrMode == ARMII::AddrMode4 || AddrMode == ARMII::AddrMode6) 6820b57cec5SDimitry Andric return Offset == 0; 6830b57cec5SDimitry Andric 6840b57cec5SDimitry Andric unsigned NumBits = 0; 6850b57cec5SDimitry Andric unsigned Scale = 1; 6860b57cec5SDimitry Andric bool isSigned = true; 6870b57cec5SDimitry Andric switch (AddrMode) { 6880b57cec5SDimitry Andric case ARMII::AddrModeT2_i8: 6890b57cec5SDimitry Andric case ARMII::AddrModeT2_i12: 6900b57cec5SDimitry Andric // i8 supports only negative, and i12 supports only positive, so 6910b57cec5SDimitry Andric // based on Offset sign, consider the appropriate instruction 6920b57cec5SDimitry Andric Scale = 1; 6930b57cec5SDimitry Andric if (Offset < 0) { 6940b57cec5SDimitry Andric NumBits = 8; 6950b57cec5SDimitry Andric Offset = -Offset; 6960b57cec5SDimitry Andric } else { 6970b57cec5SDimitry Andric NumBits = 12; 6980b57cec5SDimitry Andric } 6990b57cec5SDimitry Andric break; 7000b57cec5SDimitry Andric case ARMII::AddrMode5: 7010b57cec5SDimitry Andric // VFP address mode. 7020b57cec5SDimitry Andric NumBits = 8; 7030b57cec5SDimitry Andric Scale = 4; 7040b57cec5SDimitry Andric break; 7050b57cec5SDimitry Andric case ARMII::AddrMode_i12: 7060b57cec5SDimitry Andric case ARMII::AddrMode2: 7070b57cec5SDimitry Andric NumBits = 12; 7080b57cec5SDimitry Andric break; 7090b57cec5SDimitry Andric case ARMII::AddrMode3: 7100b57cec5SDimitry Andric NumBits = 8; 7110b57cec5SDimitry Andric break; 7120b57cec5SDimitry Andric case ARMII::AddrModeT1_s: 7130b57cec5SDimitry Andric NumBits = (BaseReg == ARM::SP ? 8 : 5); 7140b57cec5SDimitry Andric Scale = 4; 7150b57cec5SDimitry Andric isSigned = false; 7160b57cec5SDimitry Andric break; 7170b57cec5SDimitry Andric default: 7180b57cec5SDimitry Andric llvm_unreachable("Unsupported addressing mode!"); 7190b57cec5SDimitry Andric } 7200b57cec5SDimitry Andric 7210b57cec5SDimitry Andric Offset += getFrameIndexInstrOffset(MI, i); 7220b57cec5SDimitry Andric // Make sure the offset is encodable for instructions that scale the 7230b57cec5SDimitry Andric // immediate. 7240b57cec5SDimitry Andric if ((Offset & (Scale-1)) != 0) 7250b57cec5SDimitry Andric return false; 7260b57cec5SDimitry Andric 7270b57cec5SDimitry Andric if (isSigned && Offset < 0) 7280b57cec5SDimitry Andric Offset = -Offset; 7290b57cec5SDimitry Andric 7300b57cec5SDimitry Andric unsigned Mask = (1 << NumBits) - 1; 7310b57cec5SDimitry Andric if ((unsigned)Offset <= Mask * Scale) 7320b57cec5SDimitry Andric return true; 7330b57cec5SDimitry Andric 7340b57cec5SDimitry Andric return false; 7350b57cec5SDimitry Andric } 7360b57cec5SDimitry Andric 7370b57cec5SDimitry Andric void 7380b57cec5SDimitry Andric ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 7390b57cec5SDimitry Andric int SPAdj, unsigned FIOperandNum, 7400b57cec5SDimitry Andric RegScavenger *RS) const { 7410b57cec5SDimitry Andric MachineInstr &MI = *II; 7420b57cec5SDimitry Andric MachineBasicBlock &MBB = *MI.getParent(); 7430b57cec5SDimitry Andric MachineFunction &MF = *MBB.getParent(); 7440b57cec5SDimitry Andric const ARMBaseInstrInfo &TII = 7450b57cec5SDimitry Andric *static_cast<const ARMBaseInstrInfo *>(MF.getSubtarget().getInstrInfo()); 7460b57cec5SDimitry Andric const ARMFrameLowering *TFI = getFrameLowering(MF); 7470b57cec5SDimitry Andric ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 7480b57cec5SDimitry Andric assert(!AFI->isThumb1OnlyFunction() && 7490b57cec5SDimitry Andric "This eliminateFrameIndex does not support Thumb1!"); 7500b57cec5SDimitry Andric int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); 7510b57cec5SDimitry Andric unsigned FrameReg; 7520b57cec5SDimitry Andric 7530b57cec5SDimitry Andric int Offset = TFI->ResolveFrameIndexReference(MF, FrameIndex, FrameReg, SPAdj); 7540b57cec5SDimitry Andric 7550b57cec5SDimitry Andric // PEI::scavengeFrameVirtualRegs() cannot accurately track SPAdj because the 7560b57cec5SDimitry Andric // call frame setup/destroy instructions have already been eliminated. That 7570b57cec5SDimitry Andric // means the stack pointer cannot be used to access the emergency spill slot 7580b57cec5SDimitry Andric // when !hasReservedCallFrame(). 7590b57cec5SDimitry Andric #ifndef NDEBUG 7600b57cec5SDimitry Andric if (RS && FrameReg == ARM::SP && RS->isScavengingFrameIndex(FrameIndex)){ 7610b57cec5SDimitry Andric assert(TFI->hasReservedCallFrame(MF) && 7620b57cec5SDimitry Andric "Cannot use SP to access the emergency spill slot in " 7630b57cec5SDimitry Andric "functions without a reserved call frame"); 7640b57cec5SDimitry Andric assert(!MF.getFrameInfo().hasVarSizedObjects() && 7650b57cec5SDimitry Andric "Cannot use SP to access the emergency spill slot in " 7660b57cec5SDimitry Andric "functions with variable sized frame objects"); 7670b57cec5SDimitry Andric } 7680b57cec5SDimitry Andric #endif // NDEBUG 7690b57cec5SDimitry Andric 7700b57cec5SDimitry Andric assert(!MI.isDebugValue() && "DBG_VALUEs should be handled in target-independent code"); 7710b57cec5SDimitry Andric 7720b57cec5SDimitry Andric // Modify MI as necessary to handle as much of 'Offset' as possible 7730b57cec5SDimitry Andric bool Done = false; 7740b57cec5SDimitry Andric if (!AFI->isThumbFunction()) 7750b57cec5SDimitry Andric Done = rewriteARMFrameIndex(MI, FIOperandNum, FrameReg, Offset, TII); 7760b57cec5SDimitry Andric else { 7770b57cec5SDimitry Andric assert(AFI->isThumb2Function()); 7780b57cec5SDimitry Andric Done = rewriteT2FrameIndex(MI, FIOperandNum, FrameReg, Offset, TII); 7790b57cec5SDimitry Andric } 7800b57cec5SDimitry Andric if (Done) 7810b57cec5SDimitry Andric return; 7820b57cec5SDimitry Andric 7830b57cec5SDimitry Andric // If we get here, the immediate doesn't fit into the instruction. We folded 7840b57cec5SDimitry Andric // as much as possible above, handle the rest, providing a register that is 7850b57cec5SDimitry Andric // SP+LargeImm. 7860b57cec5SDimitry Andric assert((Offset || 7870b57cec5SDimitry Andric (MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrMode4 || 7880b57cec5SDimitry Andric (MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrMode6) && 7890b57cec5SDimitry Andric "This code isn't needed if offset already handled!"); 7900b57cec5SDimitry Andric 7910b57cec5SDimitry Andric unsigned ScratchReg = 0; 7920b57cec5SDimitry Andric int PIdx = MI.findFirstPredOperandIdx(); 7930b57cec5SDimitry Andric ARMCC::CondCodes Pred = (PIdx == -1) 7940b57cec5SDimitry Andric ? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm(); 7950b57cec5SDimitry Andric Register PredReg = (PIdx == -1) ? Register() : MI.getOperand(PIdx+1).getReg(); 7960b57cec5SDimitry Andric if (Offset == 0) 7970b57cec5SDimitry Andric // Must be addrmode4/6. 7980b57cec5SDimitry Andric MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false, false, false); 7990b57cec5SDimitry Andric else { 8000b57cec5SDimitry Andric ScratchReg = MF.getRegInfo().createVirtualRegister(&ARM::GPRRegClass); 8010b57cec5SDimitry Andric if (!AFI->isThumbFunction()) 8020b57cec5SDimitry Andric emitARMRegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg, 8030b57cec5SDimitry Andric Offset, Pred, PredReg, TII); 8040b57cec5SDimitry Andric else { 8050b57cec5SDimitry Andric assert(AFI->isThumb2Function()); 8060b57cec5SDimitry Andric emitT2RegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg, 8070b57cec5SDimitry Andric Offset, Pred, PredReg, TII); 8080b57cec5SDimitry Andric } 8090b57cec5SDimitry Andric // Update the original instruction to use the scratch register. 8100b57cec5SDimitry Andric MI.getOperand(FIOperandNum).ChangeToRegister(ScratchReg, false, false,true); 8110b57cec5SDimitry Andric } 8120b57cec5SDimitry Andric } 8130b57cec5SDimitry Andric 8140b57cec5SDimitry Andric bool ARMBaseRegisterInfo::shouldCoalesce(MachineInstr *MI, 8150b57cec5SDimitry Andric const TargetRegisterClass *SrcRC, 8160b57cec5SDimitry Andric unsigned SubReg, 8170b57cec5SDimitry Andric const TargetRegisterClass *DstRC, 8180b57cec5SDimitry Andric unsigned DstSubReg, 8190b57cec5SDimitry Andric const TargetRegisterClass *NewRC, 8200b57cec5SDimitry Andric LiveIntervals &LIS) const { 8210b57cec5SDimitry Andric auto MBB = MI->getParent(); 8220b57cec5SDimitry Andric auto MF = MBB->getParent(); 8230b57cec5SDimitry Andric const MachineRegisterInfo &MRI = MF->getRegInfo(); 8240b57cec5SDimitry Andric // If not copying into a sub-register this should be ok because we shouldn't 8250b57cec5SDimitry Andric // need to split the reg. 8260b57cec5SDimitry Andric if (!DstSubReg) 8270b57cec5SDimitry Andric return true; 8280b57cec5SDimitry Andric // Small registers don't frequently cause a problem, so we can coalesce them. 8290b57cec5SDimitry Andric if (getRegSizeInBits(*NewRC) < 256 && getRegSizeInBits(*DstRC) < 256 && 8300b57cec5SDimitry Andric getRegSizeInBits(*SrcRC) < 256) 8310b57cec5SDimitry Andric return true; 8320b57cec5SDimitry Andric 8330b57cec5SDimitry Andric auto NewRCWeight = 8340b57cec5SDimitry Andric MRI.getTargetRegisterInfo()->getRegClassWeight(NewRC); 8350b57cec5SDimitry Andric auto SrcRCWeight = 8360b57cec5SDimitry Andric MRI.getTargetRegisterInfo()->getRegClassWeight(SrcRC); 8370b57cec5SDimitry Andric auto DstRCWeight = 8380b57cec5SDimitry Andric MRI.getTargetRegisterInfo()->getRegClassWeight(DstRC); 8390b57cec5SDimitry Andric // If the source register class is more expensive than the destination, the 8400b57cec5SDimitry Andric // coalescing is probably profitable. 8410b57cec5SDimitry Andric if (SrcRCWeight.RegWeight > NewRCWeight.RegWeight) 8420b57cec5SDimitry Andric return true; 8430b57cec5SDimitry Andric if (DstRCWeight.RegWeight > NewRCWeight.RegWeight) 8440b57cec5SDimitry Andric return true; 8450b57cec5SDimitry Andric 8460b57cec5SDimitry Andric // If the register allocator isn't constrained, we can always allow coalescing 8470b57cec5SDimitry Andric // unfortunately we don't know yet if we will be constrained. 8480b57cec5SDimitry Andric // The goal of this heuristic is to restrict how many expensive registers 8490b57cec5SDimitry Andric // we allow to coalesce in a given basic block. 8500b57cec5SDimitry Andric auto AFI = MF->getInfo<ARMFunctionInfo>(); 8510b57cec5SDimitry Andric auto It = AFI->getCoalescedWeight(MBB); 8520b57cec5SDimitry Andric 8530b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "\tARM::shouldCoalesce - Coalesced Weight: " 8540b57cec5SDimitry Andric << It->second << "\n"); 8550b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "\tARM::shouldCoalesce - Reg Weight: " 8560b57cec5SDimitry Andric << NewRCWeight.RegWeight << "\n"); 8570b57cec5SDimitry Andric 8580b57cec5SDimitry Andric // This number is the largest round number that which meets the criteria: 8590b57cec5SDimitry Andric // (1) addresses PR18825 8600b57cec5SDimitry Andric // (2) generates better code in some test cases (like vldm-shed-a9.ll) 8610b57cec5SDimitry Andric // (3) Doesn't regress any test cases (in-tree, test-suite, and SPEC) 8620b57cec5SDimitry Andric // In practice the SizeMultiplier will only factor in for straight line code 8630b57cec5SDimitry Andric // that uses a lot of NEON vectors, which isn't terribly common. 8640b57cec5SDimitry Andric unsigned SizeMultiplier = MBB->size()/100; 8650b57cec5SDimitry Andric SizeMultiplier = SizeMultiplier ? SizeMultiplier : 1; 8660b57cec5SDimitry Andric if (It->second < NewRCWeight.WeightLimit * SizeMultiplier) { 8670b57cec5SDimitry Andric It->second += NewRCWeight.RegWeight; 8680b57cec5SDimitry Andric return true; 8690b57cec5SDimitry Andric } 8700b57cec5SDimitry Andric return false; 8710b57cec5SDimitry Andric } 872