Path: blob/main/contrib/llvm-project/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
96353 views
//===-- ARMBaseRegisterInfo.cpp - ARM Register Information ----------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file contains the base ARM implementation of TargetRegisterInfo class.9//10//===----------------------------------------------------------------------===//1112#include "ARMBaseRegisterInfo.h"13#include "ARM.h"14#include "ARMBaseInstrInfo.h"15#include "ARMFrameLowering.h"16#include "ARMMachineFunctionInfo.h"17#include "ARMSubtarget.h"18#include "MCTargetDesc/ARMAddressingModes.h"19#include "MCTargetDesc/ARMBaseInfo.h"20#include "llvm/ADT/BitVector.h"21#include "llvm/ADT/STLExtras.h"22#include "llvm/ADT/SmallVector.h"23#include "llvm/CodeGen/MachineBasicBlock.h"24#include "llvm/CodeGen/MachineConstantPool.h"25#include "llvm/CodeGen/MachineFrameInfo.h"26#include "llvm/CodeGen/MachineFunction.h"27#include "llvm/CodeGen/MachineInstr.h"28#include "llvm/CodeGen/MachineInstrBuilder.h"29#include "llvm/CodeGen/MachineOperand.h"30#include "llvm/CodeGen/MachineRegisterInfo.h"31#include "llvm/CodeGen/RegisterScavenging.h"32#include "llvm/CodeGen/TargetInstrInfo.h"33#include "llvm/CodeGen/TargetRegisterInfo.h"34#include "llvm/CodeGen/VirtRegMap.h"35#include "llvm/IR/Attributes.h"36#include "llvm/IR/Constants.h"37#include "llvm/IR/DebugLoc.h"38#include "llvm/IR/Function.h"39#include "llvm/IR/Type.h"40#include "llvm/MC/MCInstrDesc.h"41#include "llvm/Support/Debug.h"42#include "llvm/Support/ErrorHandling.h"43#include "llvm/Support/raw_ostream.h"44#include "llvm/Target/TargetMachine.h"45#include "llvm/Target/TargetOptions.h"46#include <cassert>47#include <utility>4849#define DEBUG_TYPE "arm-register-info"5051#define GET_REGINFO_TARGET_DESC52#include "ARMGenRegisterInfo.inc"5354using namespace llvm;5556ARMBaseRegisterInfo::ARMBaseRegisterInfo()57: ARMGenRegisterInfo(ARM::LR, 0, 0, ARM::PC) {58ARM_MC::initLLVMToCVRegMapping(this);59}6061const MCPhysReg*62ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {63const ARMSubtarget &STI = MF->getSubtarget<ARMSubtarget>();64bool UseSplitPush = STI.splitFramePushPop(*MF);65const Function &F = MF->getFunction();6667if (F.getCallingConv() == CallingConv::GHC) {68// GHC set of callee saved regs is empty as all those regs are69// used for passing STG regs around70return CSR_NoRegs_SaveList;71} else if (STI.splitFramePointerPush(*MF)) {72return CSR_Win_SplitFP_SaveList;73} else if (F.getCallingConv() == CallingConv::CFGuard_Check) {74return CSR_Win_AAPCS_CFGuard_Check_SaveList;75} else if (F.getCallingConv() == CallingConv::SwiftTail) {76return STI.isTargetDarwin()77? CSR_iOS_SwiftTail_SaveList78: (UseSplitPush ? CSR_ATPCS_SplitPush_SwiftTail_SaveList79: CSR_AAPCS_SwiftTail_SaveList);80} else if (F.hasFnAttribute("interrupt")) {81if (STI.isMClass()) {82// M-class CPUs have hardware which saves the registers needed to allow a83// function conforming to the AAPCS to function as a handler.84return UseSplitPush ? CSR_ATPCS_SplitPush_SaveList : CSR_AAPCS_SaveList;85} else if (F.getFnAttribute("interrupt").getValueAsString() == "FIQ") {86// Fast interrupt mode gives the handler a private copy of R8-R14, so less87// need to be saved to restore user-mode state.88return CSR_FIQ_SaveList;89} else {90// Generally only R13-R14 (i.e. SP, LR) are automatically preserved by91// exception handling.92return CSR_GenericInt_SaveList;93}94}9596if (STI.getTargetLowering()->supportSwiftError() &&97F.getAttributes().hasAttrSomewhere(Attribute::SwiftError)) {98if (STI.isTargetDarwin())99return CSR_iOS_SwiftError_SaveList;100101return UseSplitPush ? CSR_ATPCS_SplitPush_SwiftError_SaveList :102CSR_AAPCS_SwiftError_SaveList;103}104105if (STI.isTargetDarwin() && F.getCallingConv() == CallingConv::CXX_FAST_TLS)106return MF->getInfo<ARMFunctionInfo>()->isSplitCSR()107? CSR_iOS_CXX_TLS_PE_SaveList108: CSR_iOS_CXX_TLS_SaveList;109110if (STI.isTargetDarwin())111return CSR_iOS_SaveList;112113if (UseSplitPush)114return STI.createAAPCSFrameChain() ? CSR_AAPCS_SplitPush_SaveList115: CSR_ATPCS_SplitPush_SaveList;116117return CSR_AAPCS_SaveList;118}119120const MCPhysReg *ARMBaseRegisterInfo::getCalleeSavedRegsViaCopy(121const MachineFunction *MF) const {122assert(MF && "Invalid MachineFunction pointer.");123if (MF->getFunction().getCallingConv() == CallingConv::CXX_FAST_TLS &&124MF->getInfo<ARMFunctionInfo>()->isSplitCSR())125return CSR_iOS_CXX_TLS_ViaCopy_SaveList;126return nullptr;127}128129const uint32_t *130ARMBaseRegisterInfo::getCallPreservedMask(const MachineFunction &MF,131CallingConv::ID CC) const {132const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>();133if (CC == CallingConv::GHC)134// This is academic because all GHC calls are (supposed to be) tail calls135return CSR_NoRegs_RegMask;136if (CC == CallingConv::CFGuard_Check)137return CSR_Win_AAPCS_CFGuard_Check_RegMask;138if (CC == CallingConv::SwiftTail) {139return STI.isTargetDarwin() ? CSR_iOS_SwiftTail_RegMask140: CSR_AAPCS_SwiftTail_RegMask;141}142if (STI.getTargetLowering()->supportSwiftError() &&143MF.getFunction().getAttributes().hasAttrSomewhere(Attribute::SwiftError))144return STI.isTargetDarwin() ? CSR_iOS_SwiftError_RegMask145: CSR_AAPCS_SwiftError_RegMask;146147if (STI.isTargetDarwin() && CC == CallingConv::CXX_FAST_TLS)148return CSR_iOS_CXX_TLS_RegMask;149return STI.isTargetDarwin() ? CSR_iOS_RegMask : CSR_AAPCS_RegMask;150}151152const uint32_t*153ARMBaseRegisterInfo::getNoPreservedMask() const {154return CSR_NoRegs_RegMask;155}156157const uint32_t *158ARMBaseRegisterInfo::getTLSCallPreservedMask(const MachineFunction &MF) const {159assert(MF.getSubtarget<ARMSubtarget>().isTargetDarwin() &&160"only know about special TLS call on Darwin");161return CSR_iOS_TLSCall_RegMask;162}163164const uint32_t *165ARMBaseRegisterInfo::getSjLjDispatchPreservedMask(const MachineFunction &MF) const {166const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>();167if (!STI.useSoftFloat() && STI.hasVFP2Base() && !STI.isThumb1Only())168return CSR_NoRegs_RegMask;169else170return CSR_FPRegs_RegMask;171}172173const uint32_t *174ARMBaseRegisterInfo::getThisReturnPreservedMask(const MachineFunction &MF,175CallingConv::ID CC) const {176const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>();177// This should return a register mask that is the same as that returned by178// getCallPreservedMask but that additionally preserves the register used for179// the first i32 argument (which must also be the register used to return a180// single i32 return value)181//182// In case that the calling convention does not use the same register for183// both or otherwise does not want to enable this optimization, the function184// should return NULL185if (CC == CallingConv::GHC)186// This is academic because all GHC calls are (supposed to be) tail calls187return nullptr;188return STI.isTargetDarwin() ? CSR_iOS_ThisReturn_RegMask189: CSR_AAPCS_ThisReturn_RegMask;190}191192ArrayRef<MCPhysReg> ARMBaseRegisterInfo::getIntraCallClobberedRegs(193const MachineFunction *MF) const {194static const MCPhysReg IntraCallClobberedRegs[] = {ARM::R12};195return ArrayRef<MCPhysReg>(IntraCallClobberedRegs);196}197198BitVector ARMBaseRegisterInfo::199getReservedRegs(const MachineFunction &MF) const {200const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>();201const ARMFrameLowering *TFI = getFrameLowering(MF);202203// FIXME: avoid re-calculating this every time.204BitVector Reserved(getNumRegs());205markSuperRegs(Reserved, ARM::SP);206markSuperRegs(Reserved, ARM::PC);207markSuperRegs(Reserved, ARM::FPSCR);208markSuperRegs(Reserved, ARM::APSR_NZCV);209if (TFI->isFPReserved(MF))210markSuperRegs(Reserved, STI.getFramePointerReg());211if (hasBasePointer(MF))212markSuperRegs(Reserved, BasePtr);213// Some targets reserve R9.214if (STI.isR9Reserved())215markSuperRegs(Reserved, ARM::R9);216// Reserve D16-D31 if the subtarget doesn't support them.217if (!STI.hasD32()) {218static_assert(ARM::D31 == ARM::D16 + 15, "Register list not consecutive!");219for (unsigned R = 0; R < 16; ++R)220markSuperRegs(Reserved, ARM::D16 + R);221}222const TargetRegisterClass &RC = ARM::GPRPairRegClass;223for (unsigned Reg : RC)224for (MCPhysReg S : subregs(Reg))225if (Reserved.test(S))226markSuperRegs(Reserved, Reg);227// For v8.1m architecture228markSuperRegs(Reserved, ARM::ZR);229230assert(checkAllSuperRegsMarked(Reserved));231return Reserved;232}233234bool ARMBaseRegisterInfo::235isAsmClobberable(const MachineFunction &MF, MCRegister PhysReg) const {236return !getReservedRegs(MF).test(PhysReg);237}238239bool ARMBaseRegisterInfo::isInlineAsmReadOnlyReg(const MachineFunction &MF,240unsigned PhysReg) const {241const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>();242const ARMFrameLowering *TFI = getFrameLowering(MF);243244BitVector Reserved(getNumRegs());245markSuperRegs(Reserved, ARM::PC);246if (TFI->isFPReserved(MF))247markSuperRegs(Reserved, STI.getFramePointerReg());248if (hasBasePointer(MF))249markSuperRegs(Reserved, BasePtr);250assert(checkAllSuperRegsMarked(Reserved));251return Reserved.test(PhysReg);252}253254const TargetRegisterClass *255ARMBaseRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,256const MachineFunction &MF) const {257const TargetRegisterClass *Super = RC;258TargetRegisterClass::sc_iterator I = RC->getSuperClasses();259do {260switch (Super->getID()) {261case ARM::GPRRegClassID:262case ARM::SPRRegClassID:263case ARM::DPRRegClassID:264case ARM::GPRPairRegClassID:265return Super;266case ARM::QPRRegClassID:267case ARM::QQPRRegClassID:268case ARM::QQQQPRRegClassID:269if (MF.getSubtarget<ARMSubtarget>().hasNEON())270return Super;271break;272case ARM::MQPRRegClassID:273case ARM::MQQPRRegClassID:274case ARM::MQQQQPRRegClassID:275if (MF.getSubtarget<ARMSubtarget>().hasMVEIntegerOps())276return Super;277break;278}279Super = *I++;280} while (Super);281return RC;282}283284const TargetRegisterClass *285ARMBaseRegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind)286const {287return &ARM::GPRRegClass;288}289290const TargetRegisterClass *291ARMBaseRegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const {292if (RC == &ARM::CCRRegClass)293return &ARM::rGPRRegClass; // Can't copy CCR registers.294return RC;295}296297unsigned298ARMBaseRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,299MachineFunction &MF) const {300const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>();301const ARMFrameLowering *TFI = getFrameLowering(MF);302303switch (RC->getID()) {304default:305return 0;306case ARM::tGPRRegClassID: {307// hasFP ends up calling getMaxCallFrameComputed() which may not be308// available when getPressureLimit() is called as part of309// ScheduleDAGRRList.310bool HasFP = MF.getFrameInfo().isMaxCallFrameSizeComputed()311? TFI->hasFP(MF) : true;312return 5 - HasFP;313}314case ARM::GPRRegClassID: {315bool HasFP = MF.getFrameInfo().isMaxCallFrameSizeComputed()316? TFI->hasFP(MF) : true;317return 10 - HasFP - (STI.isR9Reserved() ? 1 : 0);318}319case ARM::SPRRegClassID: // Currently not used as 'rep' register class.320case ARM::DPRRegClassID:321return 32 - 10;322}323}324325// Get the other register in a GPRPair.326static MCPhysReg getPairedGPR(MCPhysReg Reg, bool Odd,327const MCRegisterInfo *RI) {328for (MCPhysReg Super : RI->superregs(Reg))329if (ARM::GPRPairRegClass.contains(Super))330return RI->getSubReg(Super, Odd ? ARM::gsub_1 : ARM::gsub_0);331return 0;332}333334// Resolve the RegPairEven / RegPairOdd register allocator hints.335bool ARMBaseRegisterInfo::getRegAllocationHints(336Register VirtReg, ArrayRef<MCPhysReg> Order,337SmallVectorImpl<MCPhysReg> &Hints, const MachineFunction &MF,338const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const {339const MachineRegisterInfo &MRI = MF.getRegInfo();340std::pair<unsigned, Register> Hint = MRI.getRegAllocationHint(VirtReg);341342unsigned Odd;343switch (Hint.first) {344case ARMRI::RegPairEven:345Odd = 0;346break;347case ARMRI::RegPairOdd:348Odd = 1;349break;350case ARMRI::RegLR:351TargetRegisterInfo::getRegAllocationHints(VirtReg, Order, Hints, MF, VRM);352if (MRI.getRegClass(VirtReg)->contains(ARM::LR))353Hints.push_back(ARM::LR);354return false;355default:356return TargetRegisterInfo::getRegAllocationHints(VirtReg, Order, Hints, MF, VRM);357}358359// This register should preferably be even (Odd == 0) or odd (Odd == 1).360// Check if the other part of the pair has already been assigned, and provide361// the paired register as the first hint.362Register Paired = Hint.second;363if (!Paired)364return false;365366Register PairedPhys;367if (Paired.isPhysical()) {368PairedPhys = Paired;369} else if (VRM && VRM->hasPhys(Paired)) {370PairedPhys = getPairedGPR(VRM->getPhys(Paired), Odd, this);371}372373// First prefer the paired physreg.374if (PairedPhys && is_contained(Order, PairedPhys))375Hints.push_back(PairedPhys);376377// Then prefer even or odd registers.378for (MCPhysReg Reg : Order) {379if (Reg == PairedPhys || (getEncodingValue(Reg) & 1) != Odd)380continue;381// Don't provide hints that are paired to a reserved register.382MCPhysReg Paired = getPairedGPR(Reg, !Odd, this);383if (!Paired || MRI.isReserved(Paired))384continue;385Hints.push_back(Reg);386}387return false;388}389390void ARMBaseRegisterInfo::updateRegAllocHint(Register Reg, Register NewReg,391MachineFunction &MF) const {392MachineRegisterInfo *MRI = &MF.getRegInfo();393std::pair<unsigned, Register> Hint = MRI->getRegAllocationHint(Reg);394if ((Hint.first == ARMRI::RegPairOdd || Hint.first == ARMRI::RegPairEven) &&395Hint.second.isVirtual()) {396// If 'Reg' is one of the even / odd register pair and it's now changed397// (e.g. coalesced) into a different register. The other register of the398// pair allocation hint must be updated to reflect the relationship399// change.400Register OtherReg = Hint.second;401Hint = MRI->getRegAllocationHint(OtherReg);402// Make sure the pair has not already divorced.403if (Hint.second == Reg) {404MRI->setRegAllocationHint(OtherReg, Hint.first, NewReg);405if (NewReg.isVirtual())406MRI->setRegAllocationHint(NewReg,407Hint.first == ARMRI::RegPairOdd408? ARMRI::RegPairEven409: ARMRI::RegPairOdd,410OtherReg);411}412}413}414415bool ARMBaseRegisterInfo::hasBasePointer(const MachineFunction &MF) const {416const MachineFrameInfo &MFI = MF.getFrameInfo();417const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();418const ARMFrameLowering *TFI = getFrameLowering(MF);419420// If we have stack realignment and VLAs, we have no pointer to use to421// access the stack. If we have stack realignment, and a large call frame,422// we have no place to allocate the emergency spill slot.423if (hasStackRealignment(MF) && !TFI->hasReservedCallFrame(MF))424return true;425426// Thumb has trouble with negative offsets from the FP. Thumb2 has a limited427// negative range for ldr/str (255), and Thumb1 is positive offsets only.428//429// It's going to be better to use the SP or Base Pointer instead. When there430// are variable sized objects, we can't reference off of the SP, so we431// reserve a Base Pointer.432//433// For Thumb2, estimate whether a negative offset from the frame pointer434// will be sufficient to reach the whole stack frame. If a function has a435// smallish frame, it's less likely to have lots of spills and callee saved436// space, so it's all more likely to be within range of the frame pointer.437// If it's wrong, the scavenger will still enable access to work, it just438// won't be optimal. (We should always be able to reach the emergency439// spill slot from the frame pointer.)440if (AFI->isThumb2Function() && MFI.hasVarSizedObjects() &&441MFI.getLocalFrameSize() >= 128)442return true;443// For Thumb1, if sp moves, nothing is in range, so force a base pointer.444// This is necessary for correctness in cases where we need an emergency445// spill slot. (In Thumb1, we can't use a negative offset from the frame446// pointer.)447if (AFI->isThumb1OnlyFunction() && !TFI->hasReservedCallFrame(MF))448return true;449return false;450}451452bool ARMBaseRegisterInfo::canRealignStack(const MachineFunction &MF) const {453const MachineRegisterInfo *MRI = &MF.getRegInfo();454const ARMFrameLowering *TFI = getFrameLowering(MF);455const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>();456// We can't realign the stack if:457// 1. Dynamic stack realignment is explicitly disabled,458// 2. There are VLAs in the function and the base pointer is disabled.459if (!TargetRegisterInfo::canRealignStack(MF))460return false;461// Stack realignment requires a frame pointer. If we already started462// register allocation with frame pointer elimination, it is too late now.463if (!MRI->canReserveReg(STI.getFramePointerReg()))464return false;465// We may also need a base pointer if there are dynamic allocas or stack466// pointer adjustments around calls.467if (TFI->hasReservedCallFrame(MF))468return true;469// A base pointer is required and allowed. Check that it isn't too late to470// reserve it.471return MRI->canReserveReg(BasePtr);472}473474bool ARMBaseRegisterInfo::475cannotEliminateFrame(const MachineFunction &MF) const {476const MachineFrameInfo &MFI = MF.getFrameInfo();477if (MF.getTarget().Options.DisableFramePointerElim(MF) && MFI.adjustsStack())478return true;479return MFI.hasVarSizedObjects() || MFI.isFrameAddressTaken() ||480hasStackRealignment(MF);481}482483Register484ARMBaseRegisterInfo::getFrameRegister(const MachineFunction &MF) const {485const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>();486const ARMFrameLowering *TFI = getFrameLowering(MF);487488if (TFI->hasFP(MF))489return STI.getFramePointerReg();490return ARM::SP;491}492493/// emitLoadConstPool - Emits a load from constpool to materialize the494/// specified immediate.495void ARMBaseRegisterInfo::emitLoadConstPool(496MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,497const DebugLoc &dl, Register DestReg, unsigned SubIdx, int Val,498ARMCC::CondCodes Pred, Register PredReg, unsigned MIFlags) const {499MachineFunction &MF = *MBB.getParent();500const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();501MachineConstantPool *ConstantPool = MF.getConstantPool();502const Constant *C =503ConstantInt::get(Type::getInt32Ty(MF.getFunction().getContext()), Val);504unsigned Idx = ConstantPool->getConstantPoolIndex(C, Align(4));505506BuildMI(MBB, MBBI, dl, TII.get(ARM::LDRcp))507.addReg(DestReg, getDefRegState(true), SubIdx)508.addConstantPoolIndex(Idx)509.addImm(0)510.add(predOps(Pred, PredReg))511.setMIFlags(MIFlags);512}513514bool ARMBaseRegisterInfo::515requiresRegisterScavenging(const MachineFunction &MF) const {516return true;517}518519bool ARMBaseRegisterInfo::520requiresFrameIndexScavenging(const MachineFunction &MF) const {521return true;522}523524bool ARMBaseRegisterInfo::525requiresVirtualBaseRegisters(const MachineFunction &MF) const {526return true;527}528529int64_t ARMBaseRegisterInfo::530getFrameIndexInstrOffset(const MachineInstr *MI, int Idx) const {531const MCInstrDesc &Desc = MI->getDesc();532unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);533int64_t InstrOffs = 0;534int Scale = 1;535unsigned ImmIdx = 0;536switch (AddrMode) {537case ARMII::AddrModeT2_i8:538case ARMII::AddrModeT2_i8neg:539case ARMII::AddrModeT2_i8pos:540case ARMII::AddrModeT2_i12:541case ARMII::AddrMode_i12:542InstrOffs = MI->getOperand(Idx+1).getImm();543Scale = 1;544break;545case ARMII::AddrMode5: {546// VFP address mode.547const MachineOperand &OffOp = MI->getOperand(Idx+1);548InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm());549if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub)550InstrOffs = -InstrOffs;551Scale = 4;552break;553}554case ARMII::AddrMode2:555ImmIdx = Idx+2;556InstrOffs = ARM_AM::getAM2Offset(MI->getOperand(ImmIdx).getImm());557if (ARM_AM::getAM2Op(MI->getOperand(ImmIdx).getImm()) == ARM_AM::sub)558InstrOffs = -InstrOffs;559break;560case ARMII::AddrMode3:561ImmIdx = Idx+2;562InstrOffs = ARM_AM::getAM3Offset(MI->getOperand(ImmIdx).getImm());563if (ARM_AM::getAM3Op(MI->getOperand(ImmIdx).getImm()) == ARM_AM::sub)564InstrOffs = -InstrOffs;565break;566case ARMII::AddrModeT1_s:567ImmIdx = Idx+1;568InstrOffs = MI->getOperand(ImmIdx).getImm();569Scale = 4;570break;571default:572llvm_unreachable("Unsupported addressing mode!");573}574575return InstrOffs * Scale;576}577578/// needsFrameBaseReg - Returns true if the instruction's frame index579/// reference would be better served by a base register other than FP580/// or SP. Used by LocalStackFrameAllocation to determine which frame index581/// references it should create new base registers for.582bool ARMBaseRegisterInfo::583needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const {584for (unsigned i = 0; !MI->getOperand(i).isFI(); ++i) {585assert(i < MI->getNumOperands() &&"Instr doesn't have FrameIndex operand!");586}587588// It's the load/store FI references that cause issues, as it can be difficult589// to materialize the offset if it won't fit in the literal field. Estimate590// based on the size of the local frame and some conservative assumptions591// about the rest of the stack frame (note, this is pre-regalloc, so592// we don't know everything for certain yet) whether this offset is likely593// to be out of range of the immediate. Return true if so.594595// We only generate virtual base registers for loads and stores, so596// return false for everything else.597unsigned Opc = MI->getOpcode();598switch (Opc) {599case ARM::LDRi12: case ARM::LDRH: case ARM::LDRBi12:600case ARM::STRi12: case ARM::STRH: case ARM::STRBi12:601case ARM::t2LDRi12: case ARM::t2LDRi8:602case ARM::t2STRi12: case ARM::t2STRi8:603case ARM::VLDRS: case ARM::VLDRD:604case ARM::VSTRS: case ARM::VSTRD:605case ARM::tSTRspi: case ARM::tLDRspi:606break;607default:608return false;609}610611// Without a virtual base register, if the function has variable sized612// objects, all fixed-size local references will be via the frame pointer,613// Approximate the offset and see if it's legal for the instruction.614// Note that the incoming offset is based on the SP value at function entry,615// so it'll be negative.616MachineFunction &MF = *MI->getParent()->getParent();617const ARMFrameLowering *TFI = getFrameLowering(MF);618MachineFrameInfo &MFI = MF.getFrameInfo();619ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();620621// Estimate an offset from the frame pointer.622// Conservatively assume all callee-saved registers get pushed. R4-R6623// will be earlier than the FP, so we ignore those.624// R7, LR625int64_t FPOffset = Offset - 8;626// ARM and Thumb2 functions also need to consider R8-R11 and D8-D15627if (!AFI->isThumbFunction() || !AFI->isThumb1OnlyFunction())628FPOffset -= 80;629// Estimate an offset from the stack pointer.630// The incoming offset is relating to the SP at the start of the function,631// but when we access the local it'll be relative to the SP after local632// allocation, so adjust our SP-relative offset by that allocation size.633Offset += MFI.getLocalFrameSize();634// Assume that we'll have at least some spill slots allocated.635// FIXME: This is a total SWAG number. We should run some statistics636// and pick a real one.637Offset += 128; // 128 bytes of spill slots638639// If there's a frame pointer and the addressing mode allows it, try using it.640// The FP is only available if there is no dynamic realignment. We641// don't know for sure yet whether we'll need that, so we guess based642// on whether there are any local variables that would trigger it.643if (TFI->hasFP(MF) &&644!((MFI.getLocalFrameMaxAlign() > TFI->getStackAlign()) &&645canRealignStack(MF))) {646if (isFrameOffsetLegal(MI, getFrameRegister(MF), FPOffset))647return false;648}649// If we can reference via the stack pointer, try that.650// FIXME: This (and the code that resolves the references) can be improved651// to only disallow SP relative references in the live range of652// the VLA(s). In practice, it's unclear how much difference that653// would make, but it may be worth doing.654if (!MFI.hasVarSizedObjects() && isFrameOffsetLegal(MI, ARM::SP, Offset))655return false;656657// The offset likely isn't legal, we want to allocate a virtual base register.658return true;659}660661/// materializeFrameBaseRegister - Insert defining instruction(s) for BaseReg to662/// be a pointer to FrameIdx at the beginning of the basic block.663Register664ARMBaseRegisterInfo::materializeFrameBaseRegister(MachineBasicBlock *MBB,665int FrameIdx,666int64_t Offset) const {667ARMFunctionInfo *AFI = MBB->getParent()->getInfo<ARMFunctionInfo>();668unsigned ADDriOpc = !AFI->isThumbFunction() ? ARM::ADDri :669(AFI->isThumb1OnlyFunction() ? ARM::tADDframe : ARM::t2ADDri);670671MachineBasicBlock::iterator Ins = MBB->begin();672DebugLoc DL; // Defaults to "unknown"673if (Ins != MBB->end())674DL = Ins->getDebugLoc();675676const MachineFunction &MF = *MBB->getParent();677MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();678const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();679const MCInstrDesc &MCID = TII.get(ADDriOpc);680Register BaseReg = MRI.createVirtualRegister(&ARM::GPRRegClass);681MRI.constrainRegClass(BaseReg, TII.getRegClass(MCID, 0, this, MF));682683MachineInstrBuilder MIB = BuildMI(*MBB, Ins, DL, MCID, BaseReg)684.addFrameIndex(FrameIdx).addImm(Offset);685686if (!AFI->isThumb1OnlyFunction())687MIB.add(predOps(ARMCC::AL)).add(condCodeOp());688689return BaseReg;690}691692void ARMBaseRegisterInfo::resolveFrameIndex(MachineInstr &MI, Register BaseReg,693int64_t Offset) const {694MachineBasicBlock &MBB = *MI.getParent();695MachineFunction &MF = *MBB.getParent();696const ARMBaseInstrInfo &TII =697*static_cast<const ARMBaseInstrInfo *>(MF.getSubtarget().getInstrInfo());698ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();699int Off = Offset; // ARM doesn't need the general 64-bit offsets700unsigned i = 0;701702assert(!AFI->isThumb1OnlyFunction() &&703"This resolveFrameIndex does not support Thumb1!");704705while (!MI.getOperand(i).isFI()) {706++i;707assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");708}709bool Done = false;710if (!AFI->isThumbFunction())711Done = rewriteARMFrameIndex(MI, i, BaseReg, Off, TII);712else {713assert(AFI->isThumb2Function());714Done = rewriteT2FrameIndex(MI, i, BaseReg, Off, TII, this);715}716assert(Done && "Unable to resolve frame index!");717(void)Done;718}719720bool ARMBaseRegisterInfo::isFrameOffsetLegal(const MachineInstr *MI,721Register BaseReg,722int64_t Offset) const {723const MCInstrDesc &Desc = MI->getDesc();724unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);725unsigned i = 0;726for (; !MI->getOperand(i).isFI(); ++i)727assert(i+1 < MI->getNumOperands() && "Instr doesn't have FrameIndex operand!");728729// AddrMode4 and AddrMode6 cannot handle any offset.730if (AddrMode == ARMII::AddrMode4 || AddrMode == ARMII::AddrMode6)731return Offset == 0;732733unsigned NumBits = 0;734unsigned Scale = 1;735bool isSigned = true;736switch (AddrMode) {737case ARMII::AddrModeT2_i8:738case ARMII::AddrModeT2_i8pos:739case ARMII::AddrModeT2_i8neg:740case ARMII::AddrModeT2_i12:741// i8 supports only negative, and i12 supports only positive, so742// based on Offset sign, consider the appropriate instruction743Scale = 1;744if (Offset < 0) {745NumBits = 8;746Offset = -Offset;747} else {748NumBits = 12;749}750break;751case ARMII::AddrMode5:752// VFP address mode.753NumBits = 8;754Scale = 4;755break;756case ARMII::AddrMode_i12:757case ARMII::AddrMode2:758NumBits = 12;759break;760case ARMII::AddrMode3:761NumBits = 8;762break;763case ARMII::AddrModeT1_s:764NumBits = (BaseReg == ARM::SP ? 8 : 5);765Scale = 4;766isSigned = false;767break;768default:769llvm_unreachable("Unsupported addressing mode!");770}771772Offset += getFrameIndexInstrOffset(MI, i);773// Make sure the offset is encodable for instructions that scale the774// immediate.775if ((Offset & (Scale-1)) != 0)776return false;777778if (isSigned && Offset < 0)779Offset = -Offset;780781unsigned Mask = (1 << NumBits) - 1;782if ((unsigned)Offset <= Mask * Scale)783return true;784785return false;786}787788bool789ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,790int SPAdj, unsigned FIOperandNum,791RegScavenger *RS) const {792MachineInstr &MI = *II;793MachineBasicBlock &MBB = *MI.getParent();794MachineFunction &MF = *MBB.getParent();795const ARMBaseInstrInfo &TII =796*static_cast<const ARMBaseInstrInfo *>(MF.getSubtarget().getInstrInfo());797const ARMFrameLowering *TFI = getFrameLowering(MF);798ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();799assert(!AFI->isThumb1OnlyFunction() &&800"This eliminateFrameIndex does not support Thumb1!");801int FrameIndex = MI.getOperand(FIOperandNum).getIndex();802Register FrameReg;803804int Offset = TFI->ResolveFrameIndexReference(MF, FrameIndex, FrameReg, SPAdj);805806// PEI::scavengeFrameVirtualRegs() cannot accurately track SPAdj because the807// call frame setup/destroy instructions have already been eliminated. That808// means the stack pointer cannot be used to access the emergency spill slot809// when !hasReservedCallFrame().810#ifndef NDEBUG811if (RS && FrameReg == ARM::SP && RS->isScavengingFrameIndex(FrameIndex)){812assert(TFI->hasReservedCallFrame(MF) &&813"Cannot use SP to access the emergency spill slot in "814"functions without a reserved call frame");815assert(!MF.getFrameInfo().hasVarSizedObjects() &&816"Cannot use SP to access the emergency spill slot in "817"functions with variable sized frame objects");818}819#endif // NDEBUG820821assert(!MI.isDebugValue() && "DBG_VALUEs should be handled in target-independent code");822823// Modify MI as necessary to handle as much of 'Offset' as possible824bool Done = false;825if (!AFI->isThumbFunction())826Done = rewriteARMFrameIndex(MI, FIOperandNum, FrameReg, Offset, TII);827else {828assert(AFI->isThumb2Function());829Done = rewriteT2FrameIndex(MI, FIOperandNum, FrameReg, Offset, TII, this);830}831if (Done)832return false;833834// If we get here, the immediate doesn't fit into the instruction. We folded835// as much as possible above, handle the rest, providing a register that is836// SP+LargeImm.837assert(838(Offset ||839(MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrMode4 ||840(MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrMode6 ||841(MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrModeT2_i7 ||842(MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrModeT2_i7s2 ||843(MI.getDesc().TSFlags & ARMII::AddrModeMask) ==844ARMII::AddrModeT2_i7s4) &&845"This code isn't needed if offset already handled!");846847unsigned ScratchReg = 0;848int PIdx = MI.findFirstPredOperandIdx();849ARMCC::CondCodes Pred = (PIdx == -1)850? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm();851Register PredReg = (PIdx == -1) ? Register() : MI.getOperand(PIdx+1).getReg();852853const MCInstrDesc &MCID = MI.getDesc();854const TargetRegisterClass *RegClass =855TII.getRegClass(MCID, FIOperandNum, this, *MI.getParent()->getParent());856857if (Offset == 0 && (FrameReg.isVirtual() || RegClass->contains(FrameReg)))858// Must be addrmode4/6.859MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false, false, false);860else {861ScratchReg = MF.getRegInfo().createVirtualRegister(RegClass);862if (!AFI->isThumbFunction())863emitARMRegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg,864Offset, Pred, PredReg, TII);865else {866assert(AFI->isThumb2Function());867emitT2RegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg,868Offset, Pred, PredReg, TII);869}870// Update the original instruction to use the scratch register.871MI.getOperand(FIOperandNum).ChangeToRegister(ScratchReg, false, false,true);872}873return false;874}875876bool ARMBaseRegisterInfo::shouldCoalesce(MachineInstr *MI,877const TargetRegisterClass *SrcRC,878unsigned SubReg,879const TargetRegisterClass *DstRC,880unsigned DstSubReg,881const TargetRegisterClass *NewRC,882LiveIntervals &LIS) const {883auto MBB = MI->getParent();884auto MF = MBB->getParent();885const MachineRegisterInfo &MRI = MF->getRegInfo();886// If not copying into a sub-register this should be ok because we shouldn't887// need to split the reg.888if (!DstSubReg)889return true;890// Small registers don't frequently cause a problem, so we can coalesce them.891if (getRegSizeInBits(*NewRC) < 256 && getRegSizeInBits(*DstRC) < 256 &&892getRegSizeInBits(*SrcRC) < 256)893return true;894895auto NewRCWeight =896MRI.getTargetRegisterInfo()->getRegClassWeight(NewRC);897auto SrcRCWeight =898MRI.getTargetRegisterInfo()->getRegClassWeight(SrcRC);899auto DstRCWeight =900MRI.getTargetRegisterInfo()->getRegClassWeight(DstRC);901// If the source register class is more expensive than the destination, the902// coalescing is probably profitable.903if (SrcRCWeight.RegWeight > NewRCWeight.RegWeight)904return true;905if (DstRCWeight.RegWeight > NewRCWeight.RegWeight)906return true;907908// If the register allocator isn't constrained, we can always allow coalescing909// unfortunately we don't know yet if we will be constrained.910// The goal of this heuristic is to restrict how many expensive registers911// we allow to coalesce in a given basic block.912auto AFI = MF->getInfo<ARMFunctionInfo>();913auto It = AFI->getCoalescedWeight(MBB);914915LLVM_DEBUG(dbgs() << "\tARM::shouldCoalesce - Coalesced Weight: "916<< It->second << "\n");917LLVM_DEBUG(dbgs() << "\tARM::shouldCoalesce - Reg Weight: "918<< NewRCWeight.RegWeight << "\n");919920// This number is the largest round number that which meets the criteria:921// (1) addresses PR18825922// (2) generates better code in some test cases (like vldm-shed-a9.ll)923// (3) Doesn't regress any test cases (in-tree, test-suite, and SPEC)924// In practice the SizeMultiplier will only factor in for straight line code925// that uses a lot of NEON vectors, which isn't terribly common.926unsigned SizeMultiplier = MBB->size()/100;927SizeMultiplier = SizeMultiplier ? SizeMultiplier : 1;928if (It->second < NewRCWeight.WeightLimit * SizeMultiplier) {929It->second += NewRCWeight.RegWeight;930return true;931}932return false;933}934935bool ARMBaseRegisterInfo::shouldRewriteCopySrc(const TargetRegisterClass *DefRC,936unsigned DefSubReg,937const TargetRegisterClass *SrcRC,938unsigned SrcSubReg) const {939// We can't extract an SPR from an arbitary DPR (as opposed to a DPR_VFP2).940if (DefRC == &ARM::SPRRegClass && DefSubReg == 0 &&941SrcRC == &ARM::DPRRegClass &&942(SrcSubReg == ARM::ssub_0 || SrcSubReg == ARM::ssub_1))943return false;944945return TargetRegisterInfo::shouldRewriteCopySrc(DefRC, DefSubReg,946SrcRC, SrcSubReg);947}948949950