131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- HexagonFrameLowering.cpp - Define frame lowering ------------------===// 2b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 3b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// The LLVM Compiler Infrastructure 4b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 5b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// This file is distributed under the University of Illinois Open Source 6b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// License. See LICENSE.TXT for details. 7b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 8b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 9b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//===----------------------------------------------------------------------===// 10f3fd7ee415ec8a6475a060e29959d04d6158f45fBenjamin Kramer 116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#define DEBUG_TYPE "hexagon-pei" 126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 13de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "HexagonBlockRanges.h" 1479aa3417eb6f58d668aadfedf075240a41d35a26Craig Topper#include "HexagonFrameLowering.h" 15b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "HexagonInstrInfo.h" 16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "HexagonMachineFunctionInfo.h" 17b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "HexagonRegisterInfo.h" 18b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "HexagonSubtarget.h" 19b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "HexagonTargetMachine.h" 20f3fd7ee415ec8a6475a060e29959d04d6158f45fBenjamin Kramer#include "llvm/ADT/BitVector.h" 216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/ADT/PostOrderIterator.h" 226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/CodeGen/MachineDominators.h" 23b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/MachineFunction.h" 24f3fd7ee415ec8a6475a060e29959d04d6158f45fBenjamin Kramer#include "llvm/CodeGen/MachineFunctionPass.h" 25d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineInstrBuilder.h" 26de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/CodeGen/MachineInstrBuilder.h" 27f3fd7ee415ec8a6475a060e29959d04d6158f45fBenjamin Kramer#include "llvm/CodeGen/MachineModuleInfo.h" 286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/CodeGen/MachinePostDominators.h" 29b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/MachineRegisterInfo.h" 30f3fd7ee415ec8a6475a060e29959d04d6158f45fBenjamin Kramer#include "llvm/CodeGen/RegisterScavenging.h" 310b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 320b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Type.h" 33d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/CommandLine.h" 346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/Support/Debug.h" 356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/Support/raw_ostream.h" 36b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Target/TargetInstrInfo.h" 37b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Target/TargetMachine.h" 38b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Target/TargetOptions.h" 39b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// Hexagon stack frame layout as defined by the ABI: 416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// 426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// Incoming arguments 436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// passed via stack 446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// | 456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// | 466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// SP during function's FP during function's | 476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// +-- runtime (top of stack) runtime (bottom) --+ | 486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// | | | 496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// --++---------------------+------------------+-----------------++-+------- 506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// | parameter area for | variable-size | fixed-size |LR| arg 516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// | called functions | local objects | local objects |FP| 526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// --+----------------------+------------------+-----------------+--+------- 536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// <- size known -> <- size unknown -> <- size known -> 546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// 556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// Low address High address 566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// 576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// <--- stack growth 586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// 596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// 606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// - In any circumstances, the outgoing function arguments are always accessi- 616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// ble using the SP, and the incoming arguments are accessible using the FP. 626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// - If the local objects are not aligned, they can always be accessed using 636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// the FP. 646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// - If there are no variable-sized objects, the local objects can always be 656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// accessed using the SP, regardless whether they are aligned or not. (The 666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// alignment padding will be at the bottom of the stack (highest address), 676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// and so the offset with respect to the SP will be known at the compile- 686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// -time.) 696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// 706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// The only complication occurs if there are both, local aligned objects, and 716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// dynamically allocated (variable-sized) objects. The alignment pad will be 726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// placed between the FP and the local objects, thus preventing the use of the 736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// FP to access the local objects. At the same time, the variable-sized objects 746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// will be between the SP and the local objects, thus introducing an unknown 756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// distance from the SP to the locals. 766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// 776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// To avoid this problem, a new register is created that holds the aligned 786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// address of the bottom of the stack, referred in the sources as AP (aligned 796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// pointer). The AP will be equal to "FP-p", where "p" is the smallest pad 806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// that aligns AP to the required boundary (a maximum of the alignments of 816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// all stack objects, fixed- and variable-sized). All local objects[1] will 826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// then use AP as the base pointer. 836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// [1] The exception is with "fixed" stack objects. "Fixed" stack objects get 846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// their name from being allocated at fixed locations on the stack, relative 856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// to the FP. In the presence of dynamic allocation and local alignment, such 866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// objects can only be accessed through the FP. 876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// 886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// Illustration of the AP: 896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// FP --+ 906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// | 916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// ---------------+---------------------+-----+-----------------------++-+-- 926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// Rest of the | Local stack objects | Pad | Fixed stack objects |LR| 936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// stack frame | (aligned) | | (CSR, spills, etc.) |FP| 946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// ---------------+---------------------+-----+-----------------+-----+--+-- 956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// |<-- Multiple of the -->| 966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// stack alignment +-- AP 976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// 986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// The AP is set up at the beginning of the function. Since it is not a dedi- 996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// cated (reserved) register, it needs to be kept live throughout the function 1006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// to be available as the base register for local object accesses. 1016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// Normally, an address of a stack objects is obtained by a pseudo-instruction 1026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// TFR_FI. To access local objects with the AP register present, a different 1036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// pseudo-instruction needs to be used: TFR_FIA. The TFR_FIA takes one extra 1046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// argument compared to TFR_FI: the first input register is the AP register. 1056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// This keeps the register live between its definition and its uses. 1066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 1076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// The AP register is originally set up using pseudo-instruction ALIGNA: 1086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// AP = ALIGNA A 1096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// where 1106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// A - required stack alignment 1116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// The alignment value must be the maximum of all alignments required by 1126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// any stack object. 1136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 1146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// The dynamic allocation uses a pseudo-instruction ALLOCA: 1156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// Rd = ALLOCA Rs, A 1166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// where 1176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// Rd - address of the allocated space 1186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// Rs - minimum size (the actual allocated can be larger to accommodate 1196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// alignment) 1206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// A - required alignment 1216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 1226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 123b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumusing namespace llvm; 124b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarstatic cl::opt<bool> DisableDeallocRet("disable-hexagon-dealloc-ret", 1266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar cl::Hidden, cl::desc("Disable Dealloc Return for Hexagon target")); 127b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 128de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic cl::opt<unsigned> NumberScavengerSlots("number-scavenger-slots", 1296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar cl::Hidden, cl::desc("Set the number of scavenger slots"), cl::init(2), 1306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar cl::ZeroOrMore); 131b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarstatic cl::opt<int> SpillFuncThreshold("spill-func-threshold", 1336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar cl::Hidden, cl::desc("Specify O2(not Os) spill func threshold"), 1346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar cl::init(6), cl::ZeroOrMore); 135b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarstatic cl::opt<int> SpillFuncThresholdOs("spill-func-threshold-Os", 1376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar cl::Hidden, cl::desc("Specify Os spill func threshold"), 1386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar cl::init(1), cl::ZeroOrMore); 139b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 140de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic cl::opt<bool> EnableStackOVFSanitizer("enable-stackovf-sanitizer", 141de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar cl::Hidden, cl::desc("Enable runtime checks for stack overflow."), 142de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar cl::init(false), cl::ZeroOrMore); 143de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarstatic cl::opt<bool> EnableShrinkWrapping("hexagon-shrink-frame", 1456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar cl::init(true), cl::Hidden, cl::ZeroOrMore, 1466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar cl::desc("Enable stack frame shrink wrapping")); 147b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarstatic cl::opt<unsigned> ShrinkLimit("shrink-frame-limit", cl::init(UINT_MAX), 1496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar cl::Hidden, cl::ZeroOrMore, cl::desc("Max count of stack frame " 1506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "shrink-wraps")); 151b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 152f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic cl::opt<bool> UseAllocframe("use-allocframe", cl::init(true), 153f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar cl::Hidden, cl::desc("Use allocframe more conservatively")); 154f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 155de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic cl::opt<bool> OptimizeSpillSlots("hexagon-opt-spill", cl::Hidden, 156de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar cl::init(true), cl::desc("Optimize spill slots")); 157de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 158f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 159f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarnamespace llvm { 160f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void initializeHexagonCallFrameInformationPass(PassRegistry&); 161f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FunctionPass *createHexagonCallFrameInformation(); 162f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 163f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 164f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarnamespace { 165f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar class HexagonCallFrameInformation : public MachineFunctionPass { 166f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar public: 167f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar static char ID; 168f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar HexagonCallFrameInformation() : MachineFunctionPass(ID) { 169f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar PassRegistry &PR = *PassRegistry::getPassRegistry(); 170f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar initializeHexagonCallFrameInformationPass(PR); 171f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 172f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool runOnMachineFunction(MachineFunction &MF) override; 173de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineFunctionProperties getRequiredProperties() const override { 174de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return MachineFunctionProperties().set( 175de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineFunctionProperties::Property::AllVRegsAllocated); 176de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 177f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar }; 178f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 179f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar char HexagonCallFrameInformation::ID = 0; 180f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 181f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 182f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonCallFrameInformation::runOnMachineFunction(MachineFunction &MF) { 183f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto &HFI = *MF.getSubtarget<HexagonSubtarget>().getFrameLowering(); 184f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool NeedCFI = MF.getMMI().hasDebugInfo() || 185f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MF.getFunction()->needsUnwindTableEntry(); 186f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 187f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!NeedCFI) 188f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 189f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar HFI.insertCFIInstructions(MF); 190f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return true; 191f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 192f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 193f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarINITIALIZE_PASS(HexagonCallFrameInformation, "hexagon-cfi", 194f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar "Hexagon call frame information", false, false) 195f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 196f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarFunctionPass *llvm::createHexagonCallFrameInformation() { 197f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return new HexagonCallFrameInformation(); 198f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 199f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 200f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 2016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarnamespace { 2026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// Map a register pair Reg to the subregister that has the greater "number", 2036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// i.e. D3 (aka R7:6) will be mapped to R7, etc. 2046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned getMax32BitSubRegister(unsigned Reg, const TargetRegisterInfo &TRI, 2056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool hireg = true) { 2066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Reg < Hexagon::D0 || Reg > Hexagon::D15) 2076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return Reg; 208b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 2096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned RegNo = 0; 2106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (MCSubRegIterator SubRegs(Reg, &TRI); SubRegs.isValid(); ++SubRegs) { 2116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (hireg) { 2126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (*SubRegs > RegNo) 2136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar RegNo = *SubRegs; 2146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } else { 2156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!RegNo || *SubRegs < RegNo) 2166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar RegNo = *SubRegs; 2176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 2186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 2196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return RegNo; 2206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 2216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 2226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// Returns the callee saved register with the largest id in the vector. 2236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned getMaxCalleeSavedReg(const std::vector<CalleeSavedInfo> &CSI, 2246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const TargetRegisterInfo &TRI) { 225de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar static_assert(Hexagon::R1 > 0, 226de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar "Assume physical registers are encoded as positive integers"); 2276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (CSI.empty()) 2286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return 0; 2296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 2306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned Max = getMax32BitSubRegister(CSI[0].getReg(), TRI); 2316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (unsigned I = 1, E = CSI.size(); I < E; ++I) { 2326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned Reg = getMax32BitSubRegister(CSI[I].getReg(), TRI); 2336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Reg > Max) 2346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Max = Reg; 2356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 2366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return Max; 2376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 2386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 2396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// Checks if the basic block contains any instruction that needs a stack 2406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// frame to be already in place. 241de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool needsStackFrame(const MachineBasicBlock &MBB, const BitVector &CSR, 242de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const HexagonRegisterInfo &HRI) { 2436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (auto &I : MBB) { 2446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MachineInstr *MI = &I; 2456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (MI->isCall()) 2466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return true; 2476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned Opc = MI->getOpcode(); 2486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar switch (Opc) { 2496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case Hexagon::ALLOCA: 2506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case Hexagon::ALIGNA: 2516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return true; 2526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar default: 2536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar break; 2546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 2556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Check individual operands. 2566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (const MachineOperand &MO : MI->operands()) { 2576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // While the presence of a frame index does not prove that a stack 2586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // frame will be required, all frame indexes should be within alloc- 2596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // frame/deallocframe. Otherwise, the code that translates a frame 2606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // index into an offset would have to be aware of the placement of 2616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // the frame creation/destruction instructions. 2626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (MO.isFI()) 2636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return true; 2646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!MO.isReg()) 2656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar continue; 2666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned R = MO.getReg(); 2676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Virtual registers will need scavenging, which then may require 2686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // a stack slot. 2696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (TargetRegisterInfo::isVirtualRegister(R)) 2706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return true; 271de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (MCSubRegIterator S(R, &HRI, true); S.isValid(); ++S) 272de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (CSR[*S]) 273de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return true; 2746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 2756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 2766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return false; 2776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 2786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 2796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// Returns true if MBB has a machine instructions that indicates a tail call 2806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// in the block. 2816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool hasTailCall(const MachineBasicBlock &MBB) { 2826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineBasicBlock::const_iterator I = MBB.getLastNonDebugInstr(); 2836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned RetOpc = I->getOpcode(); 2846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return RetOpc == Hexagon::TCRETURNi || RetOpc == Hexagon::TCRETURNr; 2856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 2866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 2876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// Returns true if MBB contains an instruction that returns. 2886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool hasReturn(const MachineBasicBlock &MBB) { 2896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (auto I = MBB.getFirstTerminator(), E = MBB.end(); I != E; ++I) 2906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (I->isReturn()) 2916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return true; 2926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return false; 2936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 294de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 295de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar /// Returns the "return" instruction from this block, or nullptr if there 296de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar /// isn't any. 297de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineInstr *getReturn(MachineBasicBlock &MBB) { 298de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &I : MBB) 299de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (I.isReturn()) 300de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return &I; 301de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return nullptr; 302de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 303de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 304de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool isRestoreCall(unsigned Opc) { 305de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar switch (Opc) { 306de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case Hexagon::RESTORE_DEALLOC_RET_JMP_V4: 307de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC: 308de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4: 309de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC: 310de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return true; 311de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 312de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return false; 313de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 314de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 315de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar inline bool isOptNone(const MachineFunction &MF) { 316de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return MF.getFunction()->hasFnAttribute(Attribute::OptimizeNone) || 317de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MF.getTarget().getOptLevel() == CodeGenOpt::None; 318de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 319de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 320de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar inline bool isOptSize(const MachineFunction &MF) { 321de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const Function &F = *MF.getFunction(); 322de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return F.optForSize() && !F.optForMinSize(); 323de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 324de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 325de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar inline bool isMinSize(const MachineFunction &MF) { 326de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return MF.getFunction()->optForMinSize(); 327de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 3286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} 3296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 3306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 3316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar/// Implements shrink-wrapping of the stack frame. By default, stack frame 3326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar/// is created in the function entry block, and is cleaned up in every block 3336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar/// that returns. This function finds alternate blocks: one for the frame 3346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar/// setup (prolog) and one for the cleanup (epilog). 3356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid HexagonFrameLowering::findShrunkPrologEpilog(MachineFunction &MF, 3366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineBasicBlock *&PrologB, MachineBasicBlock *&EpilogB) const { 3376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar static unsigned ShrinkCounter = 0; 3386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 3396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (ShrinkLimit.getPosition()) { 3406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (ShrinkCounter >= ShrinkLimit) 3416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return; 3426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ShrinkCounter++; 3436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 3446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 3456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar auto &HST = static_cast<const HexagonSubtarget&>(MF.getSubtarget()); 3466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar auto &HRI = *HST.getRegisterInfo(); 3476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 3486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineDominatorTree MDT; 3496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MDT.runOnMachineFunction(MF); 3506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachinePostDominatorTree MPT; 3516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MPT.runOnMachineFunction(MF); 3526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 3536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar typedef DenseMap<unsigned,unsigned> UnsignedMap; 3546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar UnsignedMap RPO; 3556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar typedef ReversePostOrderTraversal<const MachineFunction*> RPOTType; 3566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar RPOTType RPOT(&MF); 3576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned RPON = 0; 3586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (RPOTType::rpo_iterator I = RPOT.begin(), E = RPOT.end(); I != E; ++I) 3596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar RPO[(*I)->getNumber()] = RPON++; 3606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 3616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Don't process functions that have loops, at least for now. Placement 3626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // of prolog and epilog must take loop structure into account. For simpli- 3636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // city don't do it right now. 3646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (auto &I : MF) { 3656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned BN = RPO[I.getNumber()]; 3666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (auto SI = I.succ_begin(), SE = I.succ_end(); SI != SE; ++SI) { 3676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // If found a back-edge, return. 3686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (RPO[(*SI)->getNumber()] <= BN) 3696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return; 3706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 3716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 3726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 3736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Collect the set of blocks that need a stack frame to execute. Scan 3746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // each block for uses/defs of callee-saved registers, calls, etc. 3756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SmallVector<MachineBasicBlock*,16> SFBlocks; 3766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar BitVector CSR(Hexagon::NUM_TARGET_REGS); 3776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (const MCPhysReg *P = HRI.getCalleeSavedRegs(&MF); *P; ++P) 378de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (MCSubRegIterator S(*P, &HRI, true); S.isValid(); ++S) 379de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar CSR[*S] = true; 3806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 3816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (auto &I : MF) 382de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (needsStackFrame(I, CSR, HRI)) 3836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SFBlocks.push_back(&I); 3846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 3856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DEBUG({ 3866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar dbgs() << "Blocks needing SF: {"; 3876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (auto &B : SFBlocks) 3886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar dbgs() << " BB#" << B->getNumber(); 3896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar dbgs() << " }\n"; 3906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar }); 3916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // No frame needed? 3926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (SFBlocks.empty()) 3936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return; 3946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 3956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Pick a common dominator and a common post-dominator. 3966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineBasicBlock *DomB = SFBlocks[0]; 3976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (unsigned i = 1, n = SFBlocks.size(); i < n; ++i) { 3986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DomB = MDT.findNearestCommonDominator(DomB, SFBlocks[i]); 3996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!DomB) 4006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar break; 4016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 4026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineBasicBlock *PDomB = SFBlocks[0]; 4036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (unsigned i = 1, n = SFBlocks.size(); i < n; ++i) { 4046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar PDomB = MPT.findNearestCommonDominator(PDomB, SFBlocks[i]); 4056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!PDomB) 4066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar break; 4076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 4086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DEBUG({ 4096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar dbgs() << "Computed dom block: BB#"; 4106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (DomB) dbgs() << DomB->getNumber(); 4116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar else dbgs() << "<null>"; 4126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar dbgs() << ", computed pdom block: BB#"; 4136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (PDomB) dbgs() << PDomB->getNumber(); 4146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar else dbgs() << "<null>"; 4156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar dbgs() << "\n"; 4166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar }); 4176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!DomB || !PDomB) 4186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return; 4196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 4206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Make sure that DomB dominates PDomB and PDomB post-dominates DomB. 4216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!MDT.dominates(DomB, PDomB)) { 4226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DEBUG(dbgs() << "Dom block does not dominate pdom block\n"); 4236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return; 4246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 4256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!MPT.dominates(PDomB, DomB)) { 4266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DEBUG(dbgs() << "PDom block does not post-dominate dom block\n"); 4276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return; 4286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 4296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 4306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Finally, everything seems right. 4316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar PrologB = DomB; 4326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar EpilogB = PDomB; 4336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} 4346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 435de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 4366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar/// Perform most of the PEI work here: 4376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar/// - saving/restoring of the callee-saved registers, 4386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar/// - stack frame creation and destruction. 4396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar/// Normally, this work is distributed among various functions, but doing it 4406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar/// in one place allows shrink-wrapping of the stack frame. 4416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid HexagonFrameLowering::emitPrologue(MachineFunction &MF, 4426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineBasicBlock &MBB) const { 4436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar auto &HST = static_cast<const HexagonSubtarget&>(MF.getSubtarget()); 4446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar auto &HRI = *HST.getRegisterInfo(); 4456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 4466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineFrameInfo *MFI = MF.getFrameInfo(); 4476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 4486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 4496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineBasicBlock *PrologB = &MF.front(), *EpilogB = nullptr; 4506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (EnableShrinkWrapping) 4516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar findShrunkPrologEpilog(MF, PrologB, EpilogB); 4526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 453de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool PrologueStubs = false; 454de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar insertCSRSpillsInBlock(*PrologB, CSI, HRI, PrologueStubs); 455de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar insertPrologueInBlock(*PrologB, PrologueStubs); 4566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 4576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (EpilogB) { 4586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar insertCSRRestoresInBlock(*EpilogB, CSI, HRI); 4596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar insertEpilogueInBlock(*EpilogB); 4606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } else { 4616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (auto &B : MF) 462f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (B.isReturnBlock()) 4636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar insertCSRRestoresInBlock(B, CSI, HRI); 4646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 4656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (auto &B : MF) 466f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (B.isReturnBlock()) 4676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar insertEpilogueInBlock(B); 468de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 469de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &B : MF) { 470de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (B.empty()) 471de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar continue; 472de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineInstr *RetI = getReturn(B); 473de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!RetI || isRestoreCall(RetI->getOpcode())) 474de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar continue; 475de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &R : CSI) 476de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar RetI->addOperand(MachineOperand::CreateReg(R.getReg(), false, true)); 477de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 478de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 479de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 480de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (EpilogB) { 481de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // If there is an epilog block, it may not have a return instruction. 482de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // In such case, we need to add the callee-saved registers as live-ins 483de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // in all blocks on all paths from the epilog to any return block. 484de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned MaxBN = 0; 485de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &B : MF) 486de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (B.getNumber() >= 0) 487de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MaxBN = std::max(MaxBN, unsigned(B.getNumber())); 488de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BitVector DoneT(MaxBN+1), DoneF(MaxBN+1), Path(MaxBN+1); 489de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar updateExitPaths(*EpilogB, EpilogB, DoneT, DoneF, Path); 4906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 491b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 492b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 493b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 494de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid HexagonFrameLowering::insertPrologueInBlock(MachineBasicBlock &MBB, 495de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool PrologueStubs) const { 4966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineFunction &MF = *MBB.getParent(); 497b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineFrameInfo *MFI = MF.getFrameInfo(); 498f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto &HST = MF.getSubtarget<HexagonSubtarget>(); 4996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar auto &HII = *HST.getInstrInfo(); 5006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar auto &HRI = *HST.getRegisterInfo(); 5016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DebugLoc dl; 502b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 5036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned MaxAlign = std::max(MFI->getMaxAlignment(), getStackAlignment()); 5046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 5056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Calculate the total stack frame size. 506b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Get the number of bytes to allocate from the FrameInfo. 5076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned FrameSize = MFI->getStackSize(); 5086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Round up the max call frame size to the max alignment on the stack. 509de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned MaxCFA = alignTo(MFI->getMaxCallFrameSize(), MaxAlign); 5106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MFI->setMaxCallFrameSize(MaxCFA); 5116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 512de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar FrameSize = MaxCFA + alignTo(FrameSize, MaxAlign); 5136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MFI->setStackSize(FrameSize); 514b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 5156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool AlignStack = (MaxAlign > getStackAlignment()); 5166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 5176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Get the number of bytes to allocate from the FrameInfo. 5186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned NumBytes = MFI->getStackSize(); 5196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned SP = HRI.getStackRegister(); 5206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned MaxCF = MFI->getMaxCallFrameSize(); 521b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineBasicBlock::iterator InsertPt = MBB.begin(); 522b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 5236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar auto *FuncInfo = MF.getInfo<HexagonMachineFunctionInfo>(); 5246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar auto &AdjustRegs = FuncInfo->getAllocaAdjustInsts(); 525b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 5266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (auto MI : AdjustRegs) { 5276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar assert((MI->getOpcode() == Hexagon::ALLOCA) && "Expected alloca"); 5286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar expandAlloca(MI, HII, SP, MaxCF); 5296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MI->eraseFromParent(); 530b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 531b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 532f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!hasFP(MF)) 5336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return; 5346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 5356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Check for overflow. 5366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Hexagon_TODO: Ugh! hardcoding. Is there an API that can be used? 5376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const unsigned int ALLOCFRAME_MAX = 16384; 5386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 5396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Create a dummy memory operand to avoid allocframe from being treated as 5406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // a volatile memory reference. 5416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineMemOperand *MMO = 5426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MF.getMachineMemOperand(MachinePointerInfo(), MachineMemOperand::MOStore, 5436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 4, 4); 5446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 5456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (NumBytes >= ALLOCFRAME_MAX) { 5466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Emit allocframe(#0). 5476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe)) 5486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addImm(0) 5496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addMemOperand(MMO); 5506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 5516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Subtract offset from frame pointer. 5526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // We use a caller-saved non-parameter register for that. 5536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned CallerSavedReg = HRI.getFirstCallerSavedNonParamReg(); 5546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::CONST32_Int_Real), 5556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar CallerSavedReg).addImm(NumBytes); 5566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::A2_sub), SP) 5576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addReg(SP) 5586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addReg(CallerSavedReg); 5596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } else { 5606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe)) 5616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addImm(NumBytes) 5626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addMemOperand(MMO); 563b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 564b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 5656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (AlignStack) { 5666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::A2_andir), SP) 5676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addReg(SP) 5686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addImm(-int64_t(MaxAlign)); 5696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 570de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 571de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // If the stack-checking is enabled, and we spilled the callee-saved 572de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // registers inline (i.e. did not use a spill function), then call 573de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // the stack checker directly. 574de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (EnableStackOVFSanitizer && !PrologueStubs) 575de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::CALLstk)) 576de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addExternalSymbol("__runtime_stack_check"); 57773714eac00958b072e7356360ebc6e818b51367bMatthew Curtis} 578b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 5796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid HexagonFrameLowering::insertEpilogueInBlock(MachineBasicBlock &MBB) const { 5806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineFunction &MF = *MBB.getParent(); 581f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!hasFP(MF)) 5826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return; 5831a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma 5846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar auto &HST = static_cast<const HexagonSubtarget&>(MF.getSubtarget()); 5856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar auto &HII = *HST.getInstrInfo(); 5866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar auto &HRI = *HST.getRegisterInfo(); 5876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned SP = HRI.getStackRegister(); 5886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 589de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineInstr *RetI = getReturn(MBB); 5906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned RetOpc = RetI ? RetI->getOpcode() : 0; 5911a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma 5926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineBasicBlock::iterator InsertPt = MBB.getFirstTerminator(); 5936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DebugLoc DL; 5946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (InsertPt != MBB.end()) 5956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DL = InsertPt->getDebugLoc(); 5966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar else if (!MBB.empty()) 5976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DL = std::prev(MBB.end())->getDebugLoc(); 5986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 5996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Handle EH_RETURN. 6006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (RetOpc == Hexagon::EH_RETURN_JMPR) { 6016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar BuildMI(MBB, InsertPt, DL, HII.get(Hexagon::L2_deallocframe)); 6026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar BuildMI(MBB, InsertPt, DL, HII.get(Hexagon::A2_add), SP) 6036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addReg(SP) 6046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addReg(Hexagon::R28); 6056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return; 6066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 6076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 6086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Check for RESTORE_DEALLOC_RET* tail call. Don't emit an extra dealloc- 6096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // frame instruction if we encounter it. 610de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4 || 611de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC) { 6126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineBasicBlock::iterator It = RetI; 6136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ++It; 6146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Delete all instructions after the RESTORE (except labels). 6156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar while (It != MBB.end()) { 6166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!It->isLabel()) 6176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar It = MBB.erase(It); 6186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar else 6196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ++It; 620b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 6216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return; 6226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 6236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 6246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // It is possible that the restoring code is a call to a library function. 6256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // All of the restore* functions include "deallocframe", so we need to make 6266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // sure that we don't add an extra one. 6276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool NeedsDeallocframe = true; 6286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!MBB.empty() && InsertPt != MBB.begin()) { 6296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineBasicBlock::iterator PrevIt = std::prev(InsertPt); 6306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned COpc = PrevIt->getOpcode(); 631de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (COpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4 || 632de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar COpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC) 6336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar NeedsDeallocframe = false; 6346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 6356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 6366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!NeedsDeallocframe) 6376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return; 6386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // If the returning instruction is JMPret, replace it with dealloc_return, 6396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // otherwise just add deallocframe. The function could be returning via a 6406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // tail call. 6416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (RetOpc != Hexagon::JMPret || DisableDeallocRet) { 6426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar BuildMI(MBB, InsertPt, DL, HII.get(Hexagon::L2_deallocframe)); 6436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return; 644b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 6456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned NewOpc = Hexagon::L4_return; 6466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineInstr *NewI = BuildMI(MBB, RetI, DL, HII.get(NewOpc)); 6476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Transfer the function live-out registers. 648de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar NewI->copyImplicitOps(MF, *RetI); 6496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MBB.erase(RetI); 650b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 651b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 6526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 653de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool HexagonFrameLowering::updateExitPaths(MachineBasicBlock &MBB, 654de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineBasicBlock *RestoreB, BitVector &DoneT, BitVector &DoneF, 655de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BitVector &Path) const { 656de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert(MBB.getNumber() >= 0); 657de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned BN = MBB.getNumber(); 658de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (Path[BN] || DoneF[BN]) 659de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return false; 660de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (DoneT[BN]) 661de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return true; 662de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 663de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &CSI = MBB.getParent()->getFrameInfo()->getCalleeSavedInfo(); 664de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 665de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Path[BN] = true; 666de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool ReachedExit = false; 667de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &SB : MBB.successors()) 668de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ReachedExit |= updateExitPaths(*SB, RestoreB, DoneT, DoneF, Path); 669de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 670de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!MBB.empty() && MBB.back().isReturn()) { 671de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Add implicit uses of all callee-saved registers to the reached 672de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // return instructions. This is to prevent the anti-dependency breaker 673de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // from renaming these registers. 674de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineInstr &RetI = MBB.back(); 675de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!isRestoreCall(RetI.getOpcode())) 676de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &R : CSI) 677de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar RetI.addOperand(MachineOperand::CreateReg(R.getReg(), false, true)); 678de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ReachedExit = true; 679de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 680de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 681de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // We don't want to add unnecessary live-ins to the restore block: since 682de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // the callee-saved registers are being defined in it, the entry of the 683de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // restore block cannot be on the path from the definitions to any exit. 684de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (ReachedExit && &MBB != RestoreB) { 685de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &R : CSI) 686de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!MBB.isLiveIn(R.getReg())) 687de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MBB.addLiveIn(R.getReg()); 688de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DoneT[BN] = true; 689de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 690de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!ReachedExit) 691de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DoneF[BN] = true; 692de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 693de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Path[BN] = false; 694de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return ReachedExit; 695de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 696de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 697de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 698f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarnamespace { 699f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool IsAllocFrame(MachineBasicBlock::const_iterator It) { 700f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!It->isBundle()) 701f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return It->getOpcode() == Hexagon::S2_allocframe; 702f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto End = It->getParent()->instr_end(); 703f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock::const_instr_iterator I = It.getInstrIterator(); 704f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar while (++I != End && I->isBundled()) 705f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (I->getOpcode() == Hexagon::S2_allocframe) 706f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return true; 707f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 708f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 709f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 710f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock::iterator FindAllocFrame(MachineBasicBlock &B) { 711f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (auto &I : B) 712f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (IsAllocFrame(I)) 713f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return I; 714f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return B.end(); 715f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 716f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 717f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 718f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 719f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarvoid HexagonFrameLowering::insertCFIInstructions(MachineFunction &MF) const { 720f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (auto &B : MF) { 721f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto AF = FindAllocFrame(B); 722f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (AF == B.end()) 723f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar continue; 724f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar insertCFIInstructionsAt(B, ++AF); 725f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 726f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 727f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 728f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 729f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarvoid HexagonFrameLowering::insertCFIInstructionsAt(MachineBasicBlock &MBB, 730f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineBasicBlock::iterator At) const { 731f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineFunction &MF = *MBB.getParent(); 732de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineFrameInfo &MFI = *MF.getFrameInfo(); 733f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineModuleInfo &MMI = MF.getMMI(); 734f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto &HST = MF.getSubtarget<HexagonSubtarget>(); 735f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto &HII = *HST.getInstrInfo(); 736f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto &HRI = *HST.getRegisterInfo(); 737f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 738f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // If CFI instructions have debug information attached, something goes 739f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // wrong with the final assembly generation: the prolog_end is placed 740f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // in a wrong location. 741f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DebugLoc DL; 742f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const MCInstrDesc &CFID = HII.get(TargetOpcode::CFI_INSTRUCTION); 743f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 744f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MCSymbol *FrameLabel = MMI.getContext().createTempSymbol(); 745de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool HasFP = hasFP(MF); 746f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 747de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (HasFP) { 748f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned DwFPReg = HRI.getDwarfRegNum(HRI.getFrameRegister(), true); 749f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned DwRAReg = HRI.getDwarfRegNum(HRI.getRARegister(), true); 750f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 751f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Define CFA via an offset from the value of FP. 752f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // 753f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // -8 -4 0 (SP) 754f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // --+----+----+--------------------- 755f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // | FP | LR | increasing addresses --> 756f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // --+----+----+--------------------- 757f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // | +-- Old SP (before allocframe) 758f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // +-- New FP (after allocframe) 759f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // 760f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // MCCFIInstruction::createDefCfa subtracts the offset from the register. 761f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // MCCFIInstruction::createOffset takes the offset without sign change. 762f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto DefCfa = MCCFIInstruction::createDefCfa(FrameLabel, DwFPReg, -8); 763f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar BuildMI(MBB, At, DL, CFID) 764f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar .addCFIIndex(MMI.addFrameInst(DefCfa)); 765f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // R31 (return addr) = CFA - 4 766f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto OffR31 = MCCFIInstruction::createOffset(FrameLabel, DwRAReg, -4); 767f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar BuildMI(MBB, At, DL, CFID) 768f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar .addCFIIndex(MMI.addFrameInst(OffR31)); 769f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // R30 (frame ptr) = CFA - 8 770f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto OffR30 = MCCFIInstruction::createOffset(FrameLabel, DwFPReg, -8); 771f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar BuildMI(MBB, At, DL, CFID) 772f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar .addCFIIndex(MMI.addFrameInst(OffR30)); 773f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 774f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 775f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar static unsigned int RegsToMove[] = { 776f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Hexagon::R1, Hexagon::R0, Hexagon::R3, Hexagon::R2, 777f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Hexagon::R17, Hexagon::R16, Hexagon::R19, Hexagon::R18, 778f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Hexagon::R21, Hexagon::R20, Hexagon::R23, Hexagon::R22, 779f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Hexagon::R25, Hexagon::R24, Hexagon::R27, Hexagon::R26, 780f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Hexagon::D0, Hexagon::D1, Hexagon::D8, Hexagon::D9, 781f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Hexagon::D10, Hexagon::D11, Hexagon::D12, Hexagon::D13, 782f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Hexagon::NoRegister 783f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar }; 784f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 785de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 786f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 787f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (unsigned i = 0; RegsToMove[i] != Hexagon::NoRegister; ++i) { 788f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned Reg = RegsToMove[i]; 789f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto IfR = [Reg] (const CalleeSavedInfo &C) -> bool { 790f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return C.getReg() == Reg; 791f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar }; 792f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto F = std::find_if(CSI.begin(), CSI.end(), IfR); 793f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (F == CSI.end()) 794f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar continue; 795f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 796de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar int64_t Offset; 797de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (HasFP) { 798de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // If the function has a frame pointer (i.e. has an allocframe), 799de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // then the CFA has been defined in terms of FP. Any offsets in 800de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // the following CFI instructions have to be defined relative 801de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // to FP, which points to the bottom of the stack frame. 802de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // The function getFrameIndexReference can still choose to use SP 803de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // for the offset calculation, so we cannot simply call it here. 804de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Instead, get the offset (relative to the FP) directly. 805de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Offset = MFI.getObjectOffset(F->getFrameIdx()); 806de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } else { 807de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned FrameReg; 808de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Offset = getFrameIndexReference(MF, F->getFrameIdx(), FrameReg); 809de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 810f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Subtract 8 to make room for R30 and R31, which are added above. 811de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Offset -= 8; 812f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 813f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (Reg < Hexagon::D0 || Reg > Hexagon::D15) { 814f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned DwarfReg = HRI.getDwarfRegNum(Reg, true); 815f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto OffReg = MCCFIInstruction::createOffset(FrameLabel, DwarfReg, 816f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Offset); 817f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar BuildMI(MBB, At, DL, CFID) 818f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar .addCFIIndex(MMI.addFrameInst(OffReg)); 819f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } else { 820f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Split the double regs into subregs, and generate appropriate 821f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // cfi_offsets. 822f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // The only reason, we are split double regs is, llvm-mc does not 823f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // understand paired registers for cfi_offset. 824f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Eg .cfi_offset r1:0, -64 825f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 826f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned HiReg = HRI.getSubReg(Reg, Hexagon::subreg_hireg); 827f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned LoReg = HRI.getSubReg(Reg, Hexagon::subreg_loreg); 828f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned HiDwarfReg = HRI.getDwarfRegNum(HiReg, true); 829f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned LoDwarfReg = HRI.getDwarfRegNum(LoReg, true); 830f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto OffHi = MCCFIInstruction::createOffset(FrameLabel, HiDwarfReg, 831f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Offset+4); 832f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar BuildMI(MBB, At, DL, CFID) 833f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar .addCFIIndex(MMI.addFrameInst(OffHi)); 834f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto OffLo = MCCFIInstruction::createOffset(FrameLabel, LoDwarfReg, 835f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Offset); 836f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar BuildMI(MBB, At, DL, CFID) 837f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar .addCFIIndex(MMI.addFrameInst(OffLo)); 838f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 839f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 840f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} 841f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 842f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 843b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonFrameLowering::hasFP(const MachineFunction &MF) const { 844f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto &MFI = *MF.getFrameInfo(); 845f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo(); 846f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 847f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool HasFixed = MFI.getNumFixedObjects(); 848f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool HasPrealloc = const_cast<MachineFrameInfo&>(MFI) 849f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar .getLocalFrameObjectCount(); 850f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool HasExtraAlign = HRI.needsStackRealignment(MF); 851f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool HasAlloca = MFI.hasVarSizedObjects(); 852f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 853f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Insert ALLOCFRAME if we need to or at -O0 for the debugger. Think 854f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // that this shouldn't be required, but doing so now because gcc does and 855f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // gdb can't break at the start of the function without it. Will remove if 856f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // this turns out to be a gdb bug. 857f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // 858f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (MF.getTarget().getOptLevel() == CodeGenOpt::None) 859f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return true; 860f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 861f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // By default we want to use SP (since it's always there). FP requires 862f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // some setup (i.e. ALLOCFRAME). 863f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Fixed and preallocated objects need FP if the distance from them to 864f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // the SP is unknown (as is with alloca or aligna). 865f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if ((HasFixed || HasPrealloc) && (HasAlloca || HasExtraAlign)) 866f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return true; 867f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 868f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (MFI.getStackSize() > 0) { 869de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (EnableStackOVFSanitizer || UseAllocframe) 870f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return true; 871f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 872f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 873f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (MFI.hasCalls() || 874f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MF.getInfo<HexagonMachineFunctionInfo>()->hasClobberLR()) 875f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return true; 876f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 877f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return false; 878b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 879b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 8804aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen 8816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarenum SpillKind { 8826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SK_ToMem, 8836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SK_FromMem, 8846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SK_FromMemTailcall 8856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar}; 886b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 887de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic const char *getSpillFunctionFor(unsigned MaxReg, SpillKind SpillType, 888de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool Stkchk = false) { 8896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const char * V4SpillToMemoryFunctions[] = { 8906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "__save_r16_through_r17", 8916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "__save_r16_through_r19", 8926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "__save_r16_through_r21", 8936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "__save_r16_through_r23", 8946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "__save_r16_through_r25", 8956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "__save_r16_through_r27" }; 8966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 897de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const char * V4SpillToMemoryStkchkFunctions[] = { 898de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar "__save_r16_through_r17_stkchk", 899de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar "__save_r16_through_r19_stkchk", 900de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar "__save_r16_through_r21_stkchk", 901de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar "__save_r16_through_r23_stkchk", 902de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar "__save_r16_through_r25_stkchk", 903de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar "__save_r16_through_r27_stkchk" }; 904de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 9056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const char * V4SpillFromMemoryFunctions[] = { 9066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "__restore_r16_through_r17_and_deallocframe", 9076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "__restore_r16_through_r19_and_deallocframe", 9086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "__restore_r16_through_r21_and_deallocframe", 9096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "__restore_r16_through_r23_and_deallocframe", 9106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "__restore_r16_through_r25_and_deallocframe", 9116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "__restore_r16_through_r27_and_deallocframe" }; 9126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 9136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const char * V4SpillFromMemoryTailcallFunctions[] = { 9146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "__restore_r16_through_r17_and_deallocframe_before_tailcall", 9156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "__restore_r16_through_r19_and_deallocframe_before_tailcall", 9166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "__restore_r16_through_r21_and_deallocframe_before_tailcall", 9176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "__restore_r16_through_r23_and_deallocframe_before_tailcall", 9186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "__restore_r16_through_r25_and_deallocframe_before_tailcall", 9196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "__restore_r16_through_r27_and_deallocframe_before_tailcall" 9206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar }; 9216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 9226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const char **SpillFunc = nullptr; 9236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 9246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar switch(SpillType) { 9256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case SK_ToMem: 926de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SpillFunc = Stkchk ? V4SpillToMemoryStkchkFunctions 927de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar : V4SpillToMemoryFunctions; 9286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar break; 9296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case SK_FromMem: 9306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SpillFunc = V4SpillFromMemoryFunctions; 9316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar break; 9326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case SK_FromMemTailcall: 9336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SpillFunc = V4SpillFromMemoryTailcallFunctions; 9346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar break; 9356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 9366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar assert(SpillFunc && "Unknown spill kind"); 9376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 9386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Spill all callee-saved registers up to the highest register used. 9396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar switch (MaxReg) { 9406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case Hexagon::R17: 9416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return SpillFunc[0]; 9426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case Hexagon::R19: 9436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return SpillFunc[1]; 9446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case Hexagon::R21: 9456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return SpillFunc[2]; 9466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case Hexagon::R23: 9476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return SpillFunc[3]; 9486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case Hexagon::R25: 9496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return SpillFunc[4]; 9506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case Hexagon::R27: 9516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return SpillFunc[5]; 9526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar default: 9536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar llvm_unreachable("Unhandled maximum callee save register"); 954b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 9556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return 0; 9566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} 957b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 9586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 959f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarint HexagonFrameLowering::getFrameIndexReference(const MachineFunction &MF, 960f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar int FI, unsigned &FrameReg) const { 961f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto &MFI = *MF.getFrameInfo(); 962f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo(); 963f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 964f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar int Offset = MFI.getObjectOffset(FI); 965f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool HasAlloca = MFI.hasVarSizedObjects(); 966f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool HasExtraAlign = HRI.needsStackRealignment(MF); 967f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool NoOpt = MF.getTarget().getOptLevel() == CodeGenOpt::None; 968f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 969f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned SP = HRI.getStackRegister(), FP = HRI.getFrameRegister(); 970de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>(); 971de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned AP = HMFI.getStackAlignBasePhysReg(); 972f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned FrameSize = MFI.getStackSize(); 973f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 974f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool UseFP = false, UseAP = false; // Default: use SP (except at -O0). 975f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Use FP at -O0, except when there are objects with extra alignment. 976f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // That additional alignment requirement may cause a pad to be inserted, 977f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // which will make it impossible to use FP to access objects located 978f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // past the pad. 979f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (NoOpt && !HasExtraAlign) 980f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar UseFP = true; 981f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (MFI.isFixedObjectIndex(FI) || MFI.isObjectPreAllocated(FI)) { 982f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Fixed and preallocated objects will be located before any padding 983f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // so FP must be used to access them. 984f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar UseFP |= (HasAlloca || HasExtraAlign); 985f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } else { 986f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (HasAlloca) { 987f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (HasExtraAlign) 988f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar UseAP = true; 989f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar else 990f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar UseFP = true; 991f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 992f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 993f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 994f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // If FP was picked, then there had better be FP. 995f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool HasFP = hasFP(MF); 996f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert((HasFP || !UseFP) && "This function must have frame pointer"); 997f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 998f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Having FP implies allocframe. Allocframe will store extra 8 bytes: 999f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // FP/LR. If the base register is used to access an object across these 1000f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // 8 bytes, then the offset will need to be adjusted by 8. 1001f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // 1002f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // After allocframe: 1003f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // HexagonISelLowering adds 8 to ---+ 1004f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // the offsets of all stack-based | 1005f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // arguments (*) | 1006f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // | 1007f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // getObjectOffset < 0 0 8 getObjectOffset >= 8 1008f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // ------------------------+-----+------------------------> increasing 1009f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // <local objects> |FP/LR| <input arguments> addresses 1010f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // -----------------+------+-----+------------------------> 1011f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // | | 1012f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // SP/AP point --+ +-- FP points here (**) 1013f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // somewhere on 1014f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // this side of FP/LR 1015f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // 1016f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // (*) See LowerFormalArguments. The FP/LR is assumed to be present. 1017f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // (**) *FP == old-FP. FP+0..7 are the bytes of FP/LR. 1018f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 1019f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // The lowering assumes that FP/LR is present, and so the offsets of 1020f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // the formal arguments start at 8. If FP/LR is not there we need to 1021f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // reduce the offset by 8. 1022f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (Offset > 0 && !HasFP) 1023f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Offset -= 8; 1024f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 1025f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (UseFP) 1026f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FrameReg = FP; 1027f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar else if (UseAP) 1028f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FrameReg = AP; 1029f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar else 1030f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar FrameReg = SP; 1031f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 1032f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Calculate the actual offset in the instruction. If there is no FP 1033f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // (in other words, no allocframe), then SP will not be adjusted (i.e. 1034f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // there will be no SP -= FrameSize), so the frame size should not be 1035f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // added to the calculated offset. 1036f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar int RealOffset = Offset; 1037f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!UseFP && !UseAP && HasFP) 1038f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar RealOffset = FrameSize+Offset; 1039f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return RealOffset; 10406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} 10416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 10426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 10436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarbool HexagonFrameLowering::insertCSRSpillsInBlock(MachineBasicBlock &MBB, 1044de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const CSIVect &CSI, const HexagonRegisterInfo &HRI, 1045de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool &PrologueStubs) const { 10466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (CSI.empty()) 10476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return true; 10486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 10496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineBasicBlock::iterator MI = MBB.begin(); 1050de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar PrologueStubs = false; 10516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineFunction &MF = *MBB.getParent(); 1052f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto &HII = *MF.getSubtarget<HexagonSubtarget>().getInstrInfo(); 10536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 10546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (useSpillFunction(MF, CSI)) { 1055de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar PrologueStubs = true; 10566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned MaxReg = getMaxCalleeSavedReg(CSI, HRI); 1057de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool StkOvrFlowEnabled = EnableStackOVFSanitizer; 1058de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const char *SpillFun = getSpillFunctionFor(MaxReg, SK_ToMem, 1059de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar StkOvrFlowEnabled); 1060de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &HTM = static_cast<const HexagonTargetMachine&>(MF.getTarget()); 1061de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool IsPIC = HTM.isPositionIndependent(); 1062de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 10636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Call spill function. 10646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DebugLoc DL = MI != MBB.end() ? MI->getDebugLoc() : DebugLoc(); 1065de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned SpillOpc; 1066de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (StkOvrFlowEnabled) 1067de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4STK_PIC 1068de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar : Hexagon::SAVE_REGISTERS_CALL_V4STK; 1069de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar else 1070de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_PIC 1071de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar : Hexagon::SAVE_REGISTERS_CALL_V4; 1072de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 10736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineInstr *SaveRegsCall = 1074de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BuildMI(MBB, MI, DL, HII.get(SpillOpc)) 10756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addExternalSymbol(SpillFun); 10766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Add callee-saved registers as use. 1077de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar addCalleeSaveRegistersAsImpOperand(SaveRegsCall, CSI, false, true); 10786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Add live in registers. 10796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (unsigned I = 0; I < CSI.size(); ++I) 10806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MBB.addLiveIn(CSI[I].getReg()); 10816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return true; 10826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 10836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 10846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (unsigned i = 0, n = CSI.size(); i < n; ++i) { 1085b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum unsigned Reg = CSI[i].getReg(); 10866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Add live in registers. We treat eh_return callee saved register r0 - r3 10876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // specially. They are not really callee saved registers as they are not 10886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // supposed to be killed. 10896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool IsKill = !HRI.isEHReturnCalleeSaveReg(Reg); 10906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar int FI = CSI[i].getFrameIdx(); 10916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const TargetRegisterClass *RC = HRI.getMinimalPhysRegClass(Reg); 1092f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar HII.storeRegToStackSlot(MBB, MI, Reg, IsKill, FI, RC, &HRI); 10936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (IsKill) 10946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MBB.addLiveIn(Reg); 10956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 10966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return true; 10976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} 1098b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1099b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 11006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarbool HexagonFrameLowering::insertCSRRestoresInBlock(MachineBasicBlock &MBB, 11016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const CSIVect &CSI, const HexagonRegisterInfo &HRI) const { 11026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (CSI.empty()) 11036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return false; 11046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 11056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineBasicBlock::iterator MI = MBB.getFirstTerminator(); 11066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineFunction &MF = *MBB.getParent(); 1107f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto &HII = *MF.getSubtarget<HexagonSubtarget>().getInstrInfo(); 1108b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 11096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (useRestoreFunction(MF, CSI)) { 11106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool HasTC = hasTailCall(MBB) || !hasReturn(MBB); 11116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned MaxR = getMaxCalleeSavedReg(CSI, HRI); 11126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SpillKind Kind = HasTC ? SK_FromMemTailcall : SK_FromMem; 11136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const char *RestoreFn = getSpillFunctionFor(MaxR, Kind); 1114de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &HTM = static_cast<const HexagonTargetMachine&>(MF.getTarget()); 1115de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool IsPIC = HTM.isPositionIndependent(); 11166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 11176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Call spill function. 11186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DebugLoc DL = MI != MBB.end() ? MI->getDebugLoc() 11196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar : MBB.getLastNonDebugInstr()->getDebugLoc(); 11206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineInstr *DeallocCall = nullptr; 11216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 11226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (HasTC) { 1123de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned ROpc = IsPIC ? Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC 1124de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar : Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4; 1125f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DeallocCall = BuildMI(MBB, MI, DL, HII.get(ROpc)) 11266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addExternalSymbol(RestoreFn); 1127b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } else { 11286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // The block has a return. 11296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineBasicBlock::iterator It = MBB.getFirstTerminator(); 11306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar assert(It->isReturn() && std::next(It) == MBB.end()); 1131de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned ROpc = IsPIC ? Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC 1132de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar : Hexagon::RESTORE_DEALLOC_RET_JMP_V4; 1133f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DeallocCall = BuildMI(MBB, It, DL, HII.get(ROpc)) 11346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addExternalSymbol(RestoreFn); 11356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Transfer the function live-out registers. 1136de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DeallocCall->copyImplicitOps(MF, *It); 1137b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1138de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar addCalleeSaveRegistersAsImpOperand(DeallocCall, CSI, true, false); 11396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return true; 11406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 11416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 11426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (unsigned i = 0; i < CSI.size(); ++i) { 11436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned Reg = CSI[i].getReg(); 11446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const TargetRegisterClass *RC = HRI.getMinimalPhysRegClass(Reg); 11456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar int FI = CSI[i].getFrameIdx(); 1146f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar HII.loadRegFromStackSlot(MBB, MI, Reg, FI, RC, &HRI); 1147b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1148de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1149b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return true; 1150b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 1151b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1152de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarMachineBasicBlock::iterator HexagonFrameLowering::eliminateCallFramePseudoInstr( 1153de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineFunction &MF, MachineBasicBlock &MBB, 1154de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineBasicBlock::iterator I) const { 11556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineInstr &MI = *I; 11566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned Opc = MI.getOpcode(); 11576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar (void)Opc; // Silence compiler warning. 11586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar assert((Opc == Hexagon::ADJCALLSTACKDOWN || Opc == Hexagon::ADJCALLSTACKUP) && 11596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "Cannot handle this call frame pseudo instruction"); 1160de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return MBB.erase(I); 11616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} 11626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 11636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 11646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid HexagonFrameLowering::processFunctionBeforeFrameFinalized( 11656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineFunction &MF, RegScavenger *RS) const { 11666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // If this function has uses aligned stack and also has variable sized stack 11676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // objects, then we need to map all spill slots to fixed positions, so that 11686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // they can be accessed through FP. Otherwise they would have to be accessed 11696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // via AP, which may not be available at the particular place in the program. 11706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineFrameInfo *MFI = MF.getFrameInfo(); 11716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool HasAlloca = MFI->hasVarSizedObjects(); 1172f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool NeedsAlign = (MFI->getMaxAlignment() > getStackAlignment()); 11736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 1174f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (!HasAlloca || !NeedsAlign) 11756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return; 11766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 11776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned LFS = MFI->getLocalFrameSize(); 11786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (int i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) { 11796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!MFI->isSpillSlotObjectIndex(i) || MFI->isDeadObjectIndex(i)) 11806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar continue; 1181de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned S = MFI->getObjectSize(i); 1182de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Reduce the alignment to at most 8. This will require unaligned vector 1183de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // stores if they happen here. 1184de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned A = std::max(MFI->getObjectAlignment(i), 8U); 1185de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MFI->setObjectAlignment(i, 8); 1186de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar LFS = alignTo(LFS+S, A); 1187de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MFI->mapLocalFrameObject(i, -LFS); 11886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 11896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 11906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MFI->setLocalFrameSize(LFS); 11916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned A = MFI->getLocalFrameMaxAlign(); 11926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar assert(A <= 8 && "Unexpected local frame alignment"); 11936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (A == 0) 11946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MFI->setLocalFrameMaxAlign(8); 11956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MFI->setUseLocalStackAllocationBlock(true); 1196de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1197de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Set the physical aligned-stack base address register. 1198de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned AP = 0; 1199de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (const MachineInstr *AI = getAlignaInstr(MF)) 1200de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar AP = AI->getOperand(0).getReg(); 1201de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>(); 1202de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar HMFI.setStackAlignBasePhysReg(AP); 12036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} 1204b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1205de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar/// Returns true if there are no caller-saved registers available in class RC. 12066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarstatic bool needToReserveScavengingSpillSlots(MachineFunction &MF, 1207de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const HexagonRegisterInfo &HRI, const TargetRegisterClass *RC) { 12086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineRegisterInfo &MRI = MF.getRegInfo(); 12096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 1210de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto IsUsed = [&HRI,&MRI] (unsigned Reg) -> bool { 1211de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (MCRegAliasIterator AI(Reg, &HRI, true); AI.isValid(); ++AI) 1212de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (MRI.isPhysRegUsed(*AI)) 1213de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return true; 1214b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return false; 1215de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar }; 12166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 1217de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Check for an unused caller-saved register. Callee-saved registers 1218de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // have become pristine by now. 1219de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (const MCPhysReg *P = HRI.getCallerSavedRegs(&MF, RC); *P; ++P) 1220de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!IsUsed(*P)) 1221de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return false; 12226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 1223de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // All caller-saved registers are used. 1224de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return true; 12256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} 12266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 12276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 12286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#ifndef NDEBUG 12296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarstatic void dump_registers(BitVector &Regs, const TargetRegisterInfo &TRI) { 12306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar dbgs() << '{'; 12316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (int x = Regs.find_first(); x >= 0; x = Regs.find_next(x)) { 12326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned R = x; 12336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar dbgs() << ' ' << PrintReg(R, &TRI); 12346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 12356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar dbgs() << " }"; 12366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} 12376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#endif 12386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 12396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 12406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarbool HexagonFrameLowering::assignCalleeSavedSpillSlots(MachineFunction &MF, 12416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const TargetRegisterInfo *TRI, std::vector<CalleeSavedInfo> &CSI) const { 12426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DEBUG(dbgs() << LLVM_FUNCTION_NAME << " on " 12436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar << MF.getFunction()->getName() << '\n'); 12446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineFrameInfo *MFI = MF.getFrameInfo(); 12456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar BitVector SRegs(Hexagon::NUM_TARGET_REGS); 12466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 12476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Generate a set of unique, callee-saved registers (SRegs), where each 12486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // register in the set is maximal in terms of sub-/super-register relation, 12496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // i.e. for each R in SRegs, no proper super-register of R is also in SRegs. 12506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 12516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // (1) For each callee-saved register, add that register and all of its 12526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // sub-registers to SRegs. 12536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DEBUG(dbgs() << "Initial CS registers: {"); 12546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (unsigned i = 0, n = CSI.size(); i < n; ++i) { 12556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned R = CSI[i].getReg(); 12566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DEBUG(dbgs() << ' ' << PrintReg(R, TRI)); 12576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (MCSubRegIterator SR(R, TRI, true); SR.isValid(); ++SR) 12586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SRegs[*SR] = true; 12596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 12606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DEBUG(dbgs() << " }\n"); 12616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DEBUG(dbgs() << "SRegs.1: "; dump_registers(SRegs, *TRI); dbgs() << "\n"); 12626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 12636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // (2) For each reserved register, remove that register and all of its 12646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // sub- and super-registers from SRegs. 12656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar BitVector Reserved = TRI->getReservedRegs(MF); 12666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (int x = Reserved.find_first(); x >= 0; x = Reserved.find_next(x)) { 12676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned R = x; 12686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (MCSuperRegIterator SR(R, TRI, true); SR.isValid(); ++SR) 12696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SRegs[*SR] = false; 12706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 12716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DEBUG(dbgs() << "Res: "; dump_registers(Reserved, *TRI); dbgs() << "\n"); 12726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DEBUG(dbgs() << "SRegs.2: "; dump_registers(SRegs, *TRI); dbgs() << "\n"); 12736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 12746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // (3) Collect all registers that have at least one sub-register in SRegs, 12756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // and also have no sub-registers that are reserved. These will be the can- 12766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // didates for saving as a whole instead of their individual sub-registers. 12776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // (Saving R17:16 instead of R16 is fine, but only if R17 was not reserved.) 12786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar BitVector TmpSup(Hexagon::NUM_TARGET_REGS); 12796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (int x = SRegs.find_first(); x >= 0; x = SRegs.find_next(x)) { 12806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned R = x; 12816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (MCSuperRegIterator SR(R, TRI); SR.isValid(); ++SR) 12826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar TmpSup[*SR] = true; 12836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 12846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (int x = TmpSup.find_first(); x >= 0; x = TmpSup.find_next(x)) { 12856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned R = x; 12866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (MCSubRegIterator SR(R, TRI, true); SR.isValid(); ++SR) { 12876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!Reserved[*SR]) 12886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar continue; 12896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar TmpSup[R] = false; 12906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar break; 12916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 12926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 12936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DEBUG(dbgs() << "TmpSup: "; dump_registers(TmpSup, *TRI); dbgs() << "\n"); 12946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 12956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // (4) Include all super-registers found in (3) into SRegs. 12966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SRegs |= TmpSup; 12976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DEBUG(dbgs() << "SRegs.4: "; dump_registers(SRegs, *TRI); dbgs() << "\n"); 12986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 12996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // (5) For each register R in SRegs, if any super-register of R is in SRegs, 13006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // remove R from SRegs. 13016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (int x = SRegs.find_first(); x >= 0; x = SRegs.find_next(x)) { 13026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned R = x; 13036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (MCSuperRegIterator SR(R, TRI); SR.isValid(); ++SR) { 13046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!SRegs[*SR]) 13056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar continue; 13066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SRegs[R] = false; 13076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar break; 13086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 13096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 13106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DEBUG(dbgs() << "SRegs.5: "; dump_registers(SRegs, *TRI); dbgs() << "\n"); 13116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 13126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Now, for each register that has a fixed stack slot, create the stack 13136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // object for it. 13146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar CSI.clear(); 13156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 13166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar typedef TargetFrameLowering::SpillSlot SpillSlot; 13176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned NumFixed; 13186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar int MinOffset = 0; // CS offsets are negative. 13196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const SpillSlot *FixedSlots = getCalleeSavedSpillSlots(NumFixed); 13206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (const SpillSlot *S = FixedSlots; S != FixedSlots+NumFixed; ++S) { 13216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!SRegs[S->Reg]) 13226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar continue; 13236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(S->Reg); 13246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar int FI = MFI->CreateFixedSpillStackObject(RC->getSize(), S->Offset); 13256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MinOffset = std::min(MinOffset, S->Offset); 13266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar CSI.push_back(CalleeSavedInfo(S->Reg, FI)); 13276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SRegs[S->Reg] = false; 13286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 13296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 13306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // There can be some registers that don't have fixed slots. For example, 13316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // we need to store R0-R3 in functions with exception handling. For each 13326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // such register, create a non-fixed stack object. 13336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (int x = SRegs.find_first(); x >= 0; x = SRegs.find_next(x)) { 13346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned R = x; 13356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(R); 13366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar int Off = MinOffset - RC->getSize(); 13376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned Align = std::min(RC->getAlignment(), getStackAlignment()); 13386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar assert(isPowerOf2_32(Align)); 13396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Off &= -Align; 13406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar int FI = MFI->CreateFixedSpillStackObject(RC->getSize(), Off); 13416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MinOffset = std::min(MinOffset, Off); 13426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar CSI.push_back(CalleeSavedInfo(R, FI)); 13436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SRegs[R] = false; 13446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 13456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 13466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DEBUG({ 13476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar dbgs() << "CS information: {"; 13486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (unsigned i = 0, n = CSI.size(); i < n; ++i) { 13496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar int FI = CSI[i].getFrameIdx(); 13506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar int Off = MFI->getObjectOffset(FI); 13516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar dbgs() << ' ' << PrintReg(CSI[i].getReg(), TRI) << ":fi#" << FI << ":sp"; 13526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Off >= 0) 13536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar dbgs() << '+'; 13546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar dbgs() << Off; 1355b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 13566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar dbgs() << " }\n"; 13576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar }); 13586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 13596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#ifndef NDEBUG 13606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Verify that all registers were handled. 13616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool MissedReg = false; 13626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (int x = SRegs.find_first(); x >= 0; x = SRegs.find_next(x)) { 13636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned R = x; 13646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar dbgs() << PrintReg(R, TRI) << ' '; 13656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MissedReg = true; 1366b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 13676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (MissedReg) 13686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar llvm_unreachable("...there are unhandled callee-saved registers!"); 13696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#endif 13706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 1371b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return true; 1372b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 1373b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1374700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 1375de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool HexagonFrameLowering::expandCopy(MachineBasicBlock &B, 1376de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineBasicBlock::iterator It, MachineRegisterInfo &MRI, 1377de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const HexagonInstrInfo &HII, SmallVectorImpl<unsigned> &NewRegs) const { 1378de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineInstr *MI = &*It; 1379de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DebugLoc DL = MI->getDebugLoc(); 1380de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned DstR = MI->getOperand(0).getReg(); 1381de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned SrcR = MI->getOperand(1).getReg(); 1382de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!Hexagon::ModRegsRegClass.contains(DstR) || 1383de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar !Hexagon::ModRegsRegClass.contains(SrcR)) 1384de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return false; 1385de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1386de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned TmpR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass); 1387de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BuildMI(B, It, DL, HII.get(TargetOpcode::COPY), TmpR) 1388de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addOperand(MI->getOperand(1)); 1389de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BuildMI(B, It, DL, HII.get(TargetOpcode::COPY), DstR) 1390de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addReg(TmpR, RegState::Kill); 1391de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1392de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar NewRegs.push_back(TmpR); 1393de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar B.erase(It); 1394de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return true; 1395de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 1396de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1397de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool HexagonFrameLowering::expandStoreInt(MachineBasicBlock &B, 1398de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineBasicBlock::iterator It, MachineRegisterInfo &MRI, 1399de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const HexagonInstrInfo &HII, SmallVectorImpl<unsigned> &NewRegs) const { 1400de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineInstr *MI = &*It; 1401de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DebugLoc DL = MI->getDebugLoc(); 1402de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned Opc = MI->getOpcode(); 1403de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned SrcR = MI->getOperand(2).getReg(); 1404de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool IsKill = MI->getOperand(2).isKill(); 1405de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1406de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert(MI->getOperand(0).isFI() && "Expect a frame index"); 1407de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar int FI = MI->getOperand(0).getIndex(); 1408de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1409de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // TmpR = C2_tfrpr SrcR if SrcR is a predicate register 1410de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // TmpR = A2_tfrcrr SrcR if SrcR is a modifier register 1411de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned TmpR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass); 1412de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned TfrOpc = (Opc == Hexagon::STriw_pred) ? Hexagon::C2_tfrpr 1413de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar : Hexagon::A2_tfrcrr; 1414de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BuildMI(B, It, DL, HII.get(TfrOpc), TmpR) 1415de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addReg(SrcR, getKillRegState(IsKill)); 1416de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1417de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // S2_storeri_io FI, 0, TmpR 1418de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BuildMI(B, It, DL, HII.get(Hexagon::S2_storeri_io)) 1419de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addFrameIndex(FI) 1420de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addImm(0) 1421de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addReg(TmpR, RegState::Kill) 1422de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .setMemRefs(MI->memoperands_begin(), MI->memoperands_end()); 1423de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1424de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar NewRegs.push_back(TmpR); 1425de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar B.erase(It); 1426de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return true; 1427de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 1428de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1429de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool HexagonFrameLowering::expandLoadInt(MachineBasicBlock &B, 1430de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineBasicBlock::iterator It, MachineRegisterInfo &MRI, 1431de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const HexagonInstrInfo &HII, SmallVectorImpl<unsigned> &NewRegs) const { 1432de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineInstr *MI = &*It; 1433de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DebugLoc DL = MI->getDebugLoc(); 1434de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned Opc = MI->getOpcode(); 1435de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned DstR = MI->getOperand(0).getReg(); 1436de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1437de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert(MI->getOperand(1).isFI() && "Expect a frame index"); 1438de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar int FI = MI->getOperand(1).getIndex(); 1439de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1440de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // TmpR = L2_loadri_io FI, 0 1441de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned TmpR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass); 1442de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BuildMI(B, It, DL, HII.get(Hexagon::L2_loadri_io), TmpR) 1443de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addFrameIndex(FI) 1444de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addImm(0) 1445de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .setMemRefs(MI->memoperands_begin(), MI->memoperands_end()); 1446de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1447de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // DstR = C2_tfrrp TmpR if DstR is a predicate register 1448de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // DstR = A2_tfrrcr TmpR if DstR is a modifier register 1449de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned TfrOpc = (Opc == Hexagon::LDriw_pred) ? Hexagon::C2_tfrrp 1450de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar : Hexagon::A2_tfrrcr; 1451de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BuildMI(B, It, DL, HII.get(TfrOpc), DstR) 1452de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addReg(TmpR, RegState::Kill); 1453de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1454de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar NewRegs.push_back(TmpR); 1455de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar B.erase(It); 1456de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return true; 1457de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 1458de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1459de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1460de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool HexagonFrameLowering::expandStoreVecPred(MachineBasicBlock &B, 1461de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineBasicBlock::iterator It, MachineRegisterInfo &MRI, 1462de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const HexagonInstrInfo &HII, SmallVectorImpl<unsigned> &NewRegs) const { 1463de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &HST = B.getParent()->getSubtarget<HexagonSubtarget>(); 1464de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineInstr *MI = &*It; 1465de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DebugLoc DL = MI->getDebugLoc(); 1466de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned SrcR = MI->getOperand(2).getReg(); 1467de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool IsKill = MI->getOperand(2).isKill(); 1468de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1469de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert(MI->getOperand(0).isFI() && "Expect a frame index"); 1470de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar int FI = MI->getOperand(0).getIndex(); 1471de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1472de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool Is128B = HST.useHVXDblOps(); 1473de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto *RC = !Is128B ? &Hexagon::VectorRegsRegClass 1474de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar : &Hexagon::VectorRegs128BRegClass; 1475de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1476de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Insert transfer to general vector register. 1477de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // TmpR0 = A2_tfrsi 0x01010101 1478de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // TmpR1 = V6_vandqrt Qx, TmpR0 1479de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // store FI, 0, TmpR1 1480de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned TmpR0 = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass); 1481de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned TmpR1 = MRI.createVirtualRegister(RC); 1482de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1483de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BuildMI(B, It, DL, HII.get(Hexagon::A2_tfrsi), TmpR0) 1484de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addImm(0x01010101); 1485de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1486de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned VandOpc = !Is128B ? Hexagon::V6_vandqrt : Hexagon::V6_vandqrt_128B; 1487de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BuildMI(B, It, DL, HII.get(VandOpc), TmpR1) 1488de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addReg(SrcR, getKillRegState(IsKill)) 1489de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addReg(TmpR0, RegState::Kill); 1490de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1491de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto *HRI = B.getParent()->getSubtarget<HexagonSubtarget>().getRegisterInfo(); 1492de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar HII.storeRegToStackSlot(B, It, TmpR1, true, FI, RC, HRI); 1493de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar expandStoreVec(B, std::prev(It), MRI, HII, NewRegs); 1494de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1495de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar NewRegs.push_back(TmpR0); 1496de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar NewRegs.push_back(TmpR1); 1497de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar B.erase(It); 1498de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return true; 1499de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 1500de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1501de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool HexagonFrameLowering::expandLoadVecPred(MachineBasicBlock &B, 1502de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineBasicBlock::iterator It, MachineRegisterInfo &MRI, 1503de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const HexagonInstrInfo &HII, SmallVectorImpl<unsigned> &NewRegs) const { 1504de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &HST = B.getParent()->getSubtarget<HexagonSubtarget>(); 1505de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineInstr *MI = &*It; 1506de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DebugLoc DL = MI->getDebugLoc(); 1507de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned DstR = MI->getOperand(0).getReg(); 1508de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1509de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert(MI->getOperand(1).isFI() && "Expect a frame index"); 1510de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar int FI = MI->getOperand(1).getIndex(); 1511de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1512de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool Is128B = HST.useHVXDblOps(); 1513de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto *RC = !Is128B ? &Hexagon::VectorRegsRegClass 1514de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar : &Hexagon::VectorRegs128BRegClass; 1515de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1516de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // TmpR0 = A2_tfrsi 0x01010101 1517de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // TmpR1 = load FI, 0 1518de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // DstR = V6_vandvrt TmpR1, TmpR0 1519de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned TmpR0 = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass); 1520de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned TmpR1 = MRI.createVirtualRegister(RC); 1521de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1522de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BuildMI(B, It, DL, HII.get(Hexagon::A2_tfrsi), TmpR0) 1523de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addImm(0x01010101); 1524de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto *HRI = B.getParent()->getSubtarget<HexagonSubtarget>().getRegisterInfo(); 1525de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar HII.loadRegFromStackSlot(B, It, TmpR1, FI, RC, HRI); 1526de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar expandLoadVec(B, std::prev(It), MRI, HII, NewRegs); 1527de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1528de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned VandOpc = !Is128B ? Hexagon::V6_vandvrt : Hexagon::V6_vandvrt_128B; 1529de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BuildMI(B, It, DL, HII.get(VandOpc), DstR) 1530de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addReg(TmpR1, RegState::Kill) 1531de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addReg(TmpR0, RegState::Kill); 1532de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1533de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar NewRegs.push_back(TmpR0); 1534de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar NewRegs.push_back(TmpR1); 1535de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar B.erase(It); 1536de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return true; 1537de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 1538de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1539de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool HexagonFrameLowering::expandStoreVec2(MachineBasicBlock &B, 1540de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineBasicBlock::iterator It, MachineRegisterInfo &MRI, 1541de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const HexagonInstrInfo &HII, SmallVectorImpl<unsigned> &NewRegs) const { 1542de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineFunction &MF = *B.getParent(); 1543de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &HST = MF.getSubtarget<HexagonSubtarget>(); 1544de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &MFI = *MF.getFrameInfo(); 1545de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo(); 1546de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineInstr *MI = &*It; 1547de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DebugLoc DL = MI->getDebugLoc(); 1548de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1549de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned SrcR = MI->getOperand(2).getReg(); 1550de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned SrcLo = HRI.getSubReg(SrcR, Hexagon::subreg_loreg); 1551de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned SrcHi = HRI.getSubReg(SrcR, Hexagon::subreg_hireg); 1552de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool IsKill = MI->getOperand(2).isKill(); 1553de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1554de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert(MI->getOperand(0).isFI() && "Expect a frame index"); 1555de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar int FI = MI->getOperand(0).getIndex(); 1556de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1557de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool Is128B = HST.useHVXDblOps(); 1558de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto *RC = !Is128B ? &Hexagon::VectorRegsRegClass 1559de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar : &Hexagon::VectorRegs128BRegClass; 1560de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned Size = RC->getSize(); 1561de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned NeedAlign = RC->getAlignment(); 1562de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned HasAlign = MFI.getObjectAlignment(FI); 1563de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned StoreOpc; 1564de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1565de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Store low part. 1566de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (NeedAlign <= HasAlign) 1567de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar StoreOpc = !Is128B ? Hexagon::V6_vS32b_ai : Hexagon::V6_vS32b_ai_128B; 1568de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar else 1569de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar StoreOpc = !Is128B ? Hexagon::V6_vS32Ub_ai : Hexagon::V6_vS32Ub_ai_128B; 1570de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1571de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BuildMI(B, It, DL, HII.get(StoreOpc)) 1572de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addFrameIndex(FI) 1573de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addImm(0) 1574de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addReg(SrcLo, getKillRegState(IsKill)) 1575de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .setMemRefs(MI->memoperands_begin(), MI->memoperands_end()); 1576de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1577de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Load high part. 1578de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (NeedAlign <= MinAlign(HasAlign, Size)) 1579de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar StoreOpc = !Is128B ? Hexagon::V6_vS32b_ai : Hexagon::V6_vS32b_ai_128B; 1580de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar else 1581de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar StoreOpc = !Is128B ? Hexagon::V6_vS32Ub_ai : Hexagon::V6_vS32Ub_ai_128B; 1582de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1583de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BuildMI(B, It, DL, HII.get(StoreOpc)) 1584de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addFrameIndex(FI) 1585de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addImm(Size) 1586de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addReg(SrcHi, getKillRegState(IsKill)) 1587de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .setMemRefs(MI->memoperands_begin(), MI->memoperands_end()); 1588de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1589de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar B.erase(It); 1590de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return true; 1591de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 1592de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1593de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool HexagonFrameLowering::expandLoadVec2(MachineBasicBlock &B, 1594de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineBasicBlock::iterator It, MachineRegisterInfo &MRI, 1595de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const HexagonInstrInfo &HII, SmallVectorImpl<unsigned> &NewRegs) const { 1596de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineFunction &MF = *B.getParent(); 1597de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &HST = MF.getSubtarget<HexagonSubtarget>(); 1598de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &MFI = *MF.getFrameInfo(); 1599de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo(); 1600de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineInstr *MI = &*It; 1601de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DebugLoc DL = MI->getDebugLoc(); 1602de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1603de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned DstR = MI->getOperand(0).getReg(); 1604de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned DstHi = HRI.getSubReg(DstR, Hexagon::subreg_hireg); 1605de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned DstLo = HRI.getSubReg(DstR, Hexagon::subreg_loreg); 1606de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1607de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert(MI->getOperand(1).isFI() && "Expect a frame index"); 1608de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar int FI = MI->getOperand(1).getIndex(); 1609de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1610de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool Is128B = HST.useHVXDblOps(); 1611de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto *RC = !Is128B ? &Hexagon::VectorRegsRegClass 1612de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar : &Hexagon::VectorRegs128BRegClass; 1613de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned Size = RC->getSize(); 1614de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned NeedAlign = RC->getAlignment(); 1615de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned HasAlign = MFI.getObjectAlignment(FI); 1616de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned LoadOpc; 1617de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1618de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Load low part. 1619de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (NeedAlign <= HasAlign) 1620de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar LoadOpc = !Is128B ? Hexagon::V6_vL32b_ai : Hexagon::V6_vL32b_ai_128B; 1621de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar else 1622de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar LoadOpc = !Is128B ? Hexagon::V6_vL32Ub_ai : Hexagon::V6_vL32Ub_ai_128B; 1623de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1624de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BuildMI(B, It, DL, HII.get(LoadOpc), DstLo) 1625de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addFrameIndex(FI) 1626de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addImm(0) 1627de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .setMemRefs(MI->memoperands_begin(), MI->memoperands_end()); 1628de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1629de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Load high part. 1630de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (NeedAlign <= MinAlign(HasAlign, Size)) 1631de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar LoadOpc = !Is128B ? Hexagon::V6_vL32b_ai : Hexagon::V6_vL32b_ai_128B; 1632de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar else 1633de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar LoadOpc = !Is128B ? Hexagon::V6_vL32Ub_ai : Hexagon::V6_vL32Ub_ai_128B; 1634de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1635de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BuildMI(B, It, DL, HII.get(LoadOpc), DstHi) 1636de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addFrameIndex(FI) 1637de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addImm(Size) 1638de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .setMemRefs(MI->memoperands_begin(), MI->memoperands_end()); 1639de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1640de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar B.erase(It); 1641de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return true; 1642de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 1643de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1644de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool HexagonFrameLowering::expandStoreVec(MachineBasicBlock &B, 1645de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineBasicBlock::iterator It, MachineRegisterInfo &MRI, 1646de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const HexagonInstrInfo &HII, SmallVectorImpl<unsigned> &NewRegs) const { 1647de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineFunction &MF = *B.getParent(); 1648de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &HST = MF.getSubtarget<HexagonSubtarget>(); 1649de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &MFI = *MF.getFrameInfo(); 1650de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineInstr *MI = &*It; 1651de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DebugLoc DL = MI->getDebugLoc(); 1652de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1653de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned SrcR = MI->getOperand(2).getReg(); 1654de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool IsKill = MI->getOperand(2).isKill(); 1655de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1656de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert(MI->getOperand(0).isFI() && "Expect a frame index"); 1657de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar int FI = MI->getOperand(0).getIndex(); 1658de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1659de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool Is128B = HST.useHVXDblOps(); 1660de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto *RC = !Is128B ? &Hexagon::VectorRegsRegClass 1661de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar : &Hexagon::VectorRegs128BRegClass; 1662de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1663de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned NeedAlign = RC->getAlignment(); 1664de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned HasAlign = MFI.getObjectAlignment(FI); 1665de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned StoreOpc; 1666de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1667de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (NeedAlign <= HasAlign) 1668de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar StoreOpc = !Is128B ? Hexagon::V6_vS32b_ai : Hexagon::V6_vS32b_ai_128B; 1669de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar else 1670de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar StoreOpc = !Is128B ? Hexagon::V6_vS32Ub_ai : Hexagon::V6_vS32Ub_ai_128B; 1671de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1672de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BuildMI(B, It, DL, HII.get(StoreOpc)) 1673de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addFrameIndex(FI) 1674de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addImm(0) 1675de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addReg(SrcR, getKillRegState(IsKill)) 1676de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .setMemRefs(MI->memoperands_begin(), MI->memoperands_end()); 1677de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1678de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar B.erase(It); 1679de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return true; 1680de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 1681de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1682de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool HexagonFrameLowering::expandLoadVec(MachineBasicBlock &B, 1683de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineBasicBlock::iterator It, MachineRegisterInfo &MRI, 1684de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const HexagonInstrInfo &HII, SmallVectorImpl<unsigned> &NewRegs) const { 1685de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineFunction &MF = *B.getParent(); 1686de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &HST = MF.getSubtarget<HexagonSubtarget>(); 1687de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &MFI = *MF.getFrameInfo(); 1688de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineInstr *MI = &*It; 1689de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DebugLoc DL = MI->getDebugLoc(); 1690de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1691de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned DstR = MI->getOperand(0).getReg(); 1692de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1693de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert(MI->getOperand(1).isFI() && "Expect a frame index"); 1694de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar int FI = MI->getOperand(1).getIndex(); 1695de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1696de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool Is128B = HST.useHVXDblOps(); 1697de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto *RC = !Is128B ? &Hexagon::VectorRegsRegClass 1698de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar : &Hexagon::VectorRegs128BRegClass; 1699de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1700de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned NeedAlign = RC->getAlignment(); 1701de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned HasAlign = MFI.getObjectAlignment(FI); 1702de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned LoadOpc; 1703de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1704de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (NeedAlign <= HasAlign) 1705de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar LoadOpc = !Is128B ? Hexagon::V6_vL32b_ai : Hexagon::V6_vL32b_ai_128B; 1706de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar else 1707de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar LoadOpc = !Is128B ? Hexagon::V6_vL32Ub_ai : Hexagon::V6_vL32Ub_ai_128B; 1708de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1709de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BuildMI(B, It, DL, HII.get(LoadOpc), DstR) 1710de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addFrameIndex(FI) 1711de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addImm(0) 1712de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .setMemRefs(MI->memoperands_begin(), MI->memoperands_end()); 1713de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1714de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar B.erase(It); 1715de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return true; 1716de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 1717de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1718de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1719de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool HexagonFrameLowering::expandSpillMacros(MachineFunction &MF, 1720de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SmallVectorImpl<unsigned> &NewRegs) const { 1721de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &HST = MF.getSubtarget<HexagonSubtarget>(); 1722de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &HII = *HST.getInstrInfo(); 1723de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineRegisterInfo &MRI = MF.getRegInfo(); 1724de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool Changed = false; 1725de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1726de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &B : MF) { 1727de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Traverse the basic block. 1728de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineBasicBlock::iterator NextI; 1729de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto I = B.begin(), E = B.end(); I != E; I = NextI) { 1730de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineInstr *MI = &*I; 1731de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar NextI = std::next(I); 1732de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned Opc = MI->getOpcode(); 1733de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1734de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar switch (Opc) { 1735de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case TargetOpcode::COPY: 1736de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Changed |= expandCopy(B, I, MRI, HII, NewRegs); 1737de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 1738de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case Hexagon::STriw_pred: 1739de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case Hexagon::STriw_mod: 1740de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Changed |= expandStoreInt(B, I, MRI, HII, NewRegs); 1741de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 1742de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case Hexagon::LDriw_pred: 1743de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case Hexagon::LDriw_mod: 1744de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Changed |= expandLoadInt(B, I, MRI, HII, NewRegs); 1745de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 1746de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case Hexagon::STriq_pred_V6: 1747de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case Hexagon::STriq_pred_V6_128B: 1748de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Changed |= expandStoreVecPred(B, I, MRI, HII, NewRegs); 1749de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 1750de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case Hexagon::LDriq_pred_V6: 1751de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case Hexagon::LDriq_pred_V6_128B: 1752de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Changed |= expandLoadVecPred(B, I, MRI, HII, NewRegs); 1753de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 1754de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case Hexagon::LDrivv_pseudo_V6: 1755de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case Hexagon::LDrivv_pseudo_V6_128B: 1756de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Changed |= expandLoadVec2(B, I, MRI, HII, NewRegs); 1757de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 1758de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case Hexagon::STrivv_pseudo_V6: 1759de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case Hexagon::STrivv_pseudo_V6_128B: 1760de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Changed |= expandStoreVec2(B, I, MRI, HII, NewRegs); 1761de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 1762de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case Hexagon::STriv_pseudo_V6: 1763de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case Hexagon::STriv_pseudo_V6_128B: 1764de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Changed |= expandStoreVec(B, I, MRI, HII, NewRegs); 1765de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 1766de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case Hexagon::LDriv_pseudo_V6: 1767de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case Hexagon::LDriv_pseudo_V6_128B: 1768de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Changed |= expandLoadVec(B, I, MRI, HII, NewRegs); 1769de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 1770de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 1771de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 1772de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 1773de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1774de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Changed; 1775de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 1776de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1777de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1778de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid HexagonFrameLowering::determineCalleeSaves(MachineFunction &MF, 1779de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BitVector &SavedRegs, 1780de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar RegScavenger *RS) const { 1781de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &HST = MF.getSubtarget<HexagonSubtarget>(); 1782de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &HRI = *HST.getRegisterInfo(); 1783de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1784de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SavedRegs.resize(HRI.getNumRegs()); 1785de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1786de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // If we have a function containing __builtin_eh_return we want to spill and 1787de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // restore all callee saved registers. Pretend that they are used. 1788de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (MF.getInfo<HexagonMachineFunctionInfo>()->hasEHReturn()) 1789de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (const MCPhysReg *R = HRI.getCalleeSavedRegs(&MF); *R; ++R) 1790de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SavedRegs.set(*R); 1791de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1792de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Replace predicate register pseudo spill code. 1793de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SmallVector<unsigned,8> NewRegs; 1794de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar expandSpillMacros(MF, NewRegs); 1795de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (OptimizeSpillSlots && !isOptNone(MF)) 1796de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar optimizeSpillSlots(MF, NewRegs); 1797de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1798de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // We need to reserve a a spill slot if scavenging could potentially require 1799de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // spilling a scavenged register. 1800de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!NewRegs.empty()) { 1801de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineFrameInfo &MFI = *MF.getFrameInfo(); 1802de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineRegisterInfo &MRI = MF.getRegInfo(); 1803de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SetVector<const TargetRegisterClass*> SpillRCs; 1804de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Reserve an int register in any case, because it could be used to hold 1805de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // the stack offset in case it does not fit into a spill instruction. 1806de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SpillRCs.insert(&Hexagon::IntRegsRegClass); 1807de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1808de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (unsigned VR : NewRegs) 1809de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SpillRCs.insert(MRI.getRegClass(VR)); 1810de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1811de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto *RC : SpillRCs) { 1812de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!needToReserveScavengingSpillSlots(MF, HRI, RC)) 1813de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar continue; 1814de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned Num = RC == &Hexagon::IntRegsRegClass ? NumberScavengerSlots : 1; 1815de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned S = RC->getSize(), A = RC->getAlignment(); 1816de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (unsigned i = 0; i < Num; i++) { 1817de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar int NewFI = MFI.CreateSpillStackObject(S, A); 1818de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar RS->addScavengingFrameIndex(NewFI); 1819de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 1820de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 1821de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 1822de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1823de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); 1824de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 1825de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1826de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1827de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarunsigned HexagonFrameLowering::findPhysReg(MachineFunction &MF, 1828de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar HexagonBlockRanges::IndexRange &FIR, 1829de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar HexagonBlockRanges::InstrIndexMap &IndexMap, 1830de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar HexagonBlockRanges::RegToRangeMap &DeadMap, 1831de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const TargetRegisterClass *RC) const { 1832de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo(); 1833de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &MRI = MF.getRegInfo(); 1834de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1835de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto isDead = [&FIR,&DeadMap] (unsigned Reg) -> bool { 1836de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto F = DeadMap.find({Reg,0}); 1837de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (F == DeadMap.end()) 1838de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return false; 1839de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &DR : F->second) 1840de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (DR.contains(FIR)) 1841de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return true; 1842de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return false; 1843de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar }; 1844de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1845de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (unsigned Reg : RC->getRawAllocationOrder(MF)) { 1846de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool Dead = true; 1847de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto R : HexagonBlockRanges::expandToSubRegs({Reg,0}, MRI, HRI)) { 1848de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (isDead(R.Reg)) 1849de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar continue; 1850de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Dead = false; 1851de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 1852de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 1853de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (Dead) 1854de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Reg; 1855de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 1856de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return 0; 1857de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 1858de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1859de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid HexagonFrameLowering::optimizeSpillSlots(MachineFunction &MF, 1860de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SmallVectorImpl<unsigned> &VRegs) const { 1861de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &HST = MF.getSubtarget<HexagonSubtarget>(); 1862de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &HII = *HST.getInstrInfo(); 1863de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &HRI = *HST.getRegisterInfo(); 1864de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &MRI = MF.getRegInfo(); 1865de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar HexagonBlockRanges HBR(MF); 1866de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1867de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar typedef std::map<MachineBasicBlock*,HexagonBlockRanges::InstrIndexMap> 1868de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BlockIndexMap; 1869de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar typedef std::map<MachineBasicBlock*,HexagonBlockRanges::RangeList> 1870de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BlockRangeMap; 1871de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar typedef HexagonBlockRanges::IndexType IndexType; 1872de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1873de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar struct SlotInfo { 1874de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BlockRangeMap Map; 1875de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned Size; 1876de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const TargetRegisterClass *RC; 1877de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1878de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SlotInfo() : Map(), Size(0), RC(nullptr) {} 1879de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar }; 1880de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1881de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BlockIndexMap BlockIndexes; 1882de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SmallSet<int,4> BadFIs; 1883de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar std::map<int,SlotInfo> FIRangeMap; 1884de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1885de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto getRegClass = [&MRI,&HRI] (HexagonBlockRanges::RegisterRef R) 1886de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar -> const TargetRegisterClass* { 1887de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (TargetRegisterInfo::isPhysicalRegister(R.Reg)) 1888de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert(R.Sub == 0); 1889de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (TargetRegisterInfo::isVirtualRegister(R.Reg)) { 1890de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto *RCR = MRI.getRegClass(R.Reg); 1891de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (R.Sub == 0) 1892de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return RCR; 1893de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned PR = *RCR->begin(); 1894de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar R.Reg = HRI.getSubReg(PR, R.Sub); 1895de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 1896de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return HRI.getMinimalPhysRegClass(R.Reg); 1897de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar }; 1898de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Accumulate register classes: get a common class for a pre-existing 1899de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // class HaveRC and a new class NewRC. Return nullptr if a common class 1900de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // cannot be found, otherwise return the resulting class. If HaveRC is 1901de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // nullptr, assume that it is still unset. 1902de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto getCommonRC = [&HRI] (const TargetRegisterClass *HaveRC, 1903de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const TargetRegisterClass *NewRC) 1904de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar -> const TargetRegisterClass* { 1905de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (HaveRC == nullptr || HaveRC == NewRC) 1906de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return NewRC; 1907de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Different classes, both non-null. Pick the more general one. 1908de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (HaveRC->hasSubClassEq(NewRC)) 1909de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return HaveRC; 1910de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (NewRC->hasSubClassEq(HaveRC)) 1911de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return NewRC; 1912de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return nullptr; 1913de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar }; 1914de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1915de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Scan all blocks in the function. Check all occurrences of frame indexes, 1916de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // and collect relevant information. 1917de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &B : MF) { 1918de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar std::map<int,IndexType> LastStore, LastLoad; 1919de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Emplace appears not to be supported in gcc 4.7.2-4. 1920de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar //auto P = BlockIndexes.emplace(&B, HexagonBlockRanges::InstrIndexMap(B)); 1921de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto P = BlockIndexes.insert( 1922de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar std::make_pair(&B, HexagonBlockRanges::InstrIndexMap(B))); 1923de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &IndexMap = P.first->second; 1924de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DEBUG(dbgs() << "Index map for BB#" << B.getNumber() << "\n" 1925de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar << IndexMap << '\n'); 1926de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1927de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &In : B) { 1928de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar int LFI, SFI; 1929de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool Load = HII.isLoadFromStackSlot(In, LFI) && !HII.isPredicated(In); 1930de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool Store = HII.isStoreToStackSlot(In, SFI) && !HII.isPredicated(In); 1931de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (Load && Store) { 1932de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // If it's both a load and a store, then we won't handle it. 1933de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BadFIs.insert(LFI); 1934de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BadFIs.insert(SFI); 1935de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar continue; 1936de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 1937de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Check for register classes of the register used as the source for 1938de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // the store, and the register used as the destination for the load. 1939de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Also, only accept base+imm_offset addressing modes. Other addressing 1940de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // modes can have side-effects (post-increments, etc.). For stack 1941de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // slots they are very unlikely, so there is not much loss due to 1942de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // this restriction. 1943de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (Load || Store) { 1944de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar int TFI = Load ? LFI : SFI; 1945de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned AM = HII.getAddrMode(&In); 1946de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SlotInfo &SI = FIRangeMap[TFI]; 1947de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool Bad = (AM != HexagonII::BaseImmOffset); 1948de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!Bad) { 1949de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // If the addressing mode is ok, check the register class. 1950de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const TargetRegisterClass *RC = nullptr; 1951de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (Load) { 1952de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineOperand &DataOp = In.getOperand(0); 1953de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar RC = getRegClass({DataOp.getReg(), DataOp.getSubReg()}); 1954de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } else { 1955de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineOperand &DataOp = In.getOperand(2); 1956de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar RC = getRegClass({DataOp.getReg(), DataOp.getSubReg()}); 1957de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 1958de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar RC = getCommonRC(SI.RC, RC); 1959de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (RC == nullptr) 1960de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Bad = true; 1961de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar else 1962de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SI.RC = RC; 1963de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 1964de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!Bad) { 1965de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Check sizes. 1966de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned S = (1U << (HII.getMemAccessSize(&In) - 1)); 1967de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (SI.Size != 0 && SI.Size != S) 1968de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Bad = true; 1969de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar else 1970de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SI.Size = S; 1971de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 1972de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (Bad) 1973de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BadFIs.insert(TFI); 1974de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 1975de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1976de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Locate uses of frame indices. 1977de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (unsigned i = 0, n = In.getNumOperands(); i < n; ++i) { 1978de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const MachineOperand &Op = In.getOperand(i); 1979de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!Op.isFI()) 1980de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar continue; 1981de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar int FI = Op.getIndex(); 1982de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Make sure that the following operand is an immediate and that 1983de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // it is 0. This is the offset in the stack object. 1984de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (i+1 >= n || !In.getOperand(i+1).isImm() || 1985de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar In.getOperand(i+1).getImm() != 0) 1986de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BadFIs.insert(FI); 1987de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (BadFIs.count(FI)) 1988de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar continue; 1989de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 1990de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar IndexType Index = IndexMap.getIndex(&In); 1991de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (Load) { 1992de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (LastStore[FI] == IndexType::None) 1993de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar LastStore[FI] = IndexType::Entry; 1994de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar LastLoad[FI] = Index; 1995de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } else if (Store) { 1996de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar HexagonBlockRanges::RangeList &RL = FIRangeMap[FI].Map[&B]; 1997de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (LastStore[FI] != IndexType::None) 1998de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar RL.add(LastStore[FI], LastLoad[FI], false, false); 1999de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar else if (LastLoad[FI] != IndexType::None) 2000de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar RL.add(IndexType::Entry, LastLoad[FI], false, false); 2001de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar LastLoad[FI] = IndexType::None; 2002de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar LastStore[FI] = Index; 2003de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } else { 2004de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BadFIs.insert(FI); 2005de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 2006de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 2007de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 2008de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 2009de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &I : LastLoad) { 2010de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar IndexType LL = I.second; 2011de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (LL == IndexType::None) 2012de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar continue; 2013de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &RL = FIRangeMap[I.first].Map[&B]; 2014de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar IndexType &LS = LastStore[I.first]; 2015de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (LS != IndexType::None) 2016de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar RL.add(LS, LL, false, false); 2017de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar else 2018de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar RL.add(IndexType::Entry, LL, false, false); 2019de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar LS = IndexType::None; 2020de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 2021de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &I : LastStore) { 2022de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar IndexType LS = I.second; 2023de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (LS == IndexType::None) 2024de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar continue; 2025de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &RL = FIRangeMap[I.first].Map[&B]; 2026de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar RL.add(LS, IndexType::None, false, false); 2027de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 2028de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 2029de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 2030de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DEBUG({ 2031de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &P : FIRangeMap) { 2032de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar dbgs() << "fi#" << P.first; 2033de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (BadFIs.count(P.first)) 2034de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar dbgs() << " (bad)"; 2035de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar dbgs() << " RC: "; 2036de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (P.second.RC != nullptr) 2037de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar dbgs() << HRI.getRegClassName(P.second.RC) << '\n'; 2038de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar else 2039de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar dbgs() << "<null>\n"; 2040de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &R : P.second.Map) 2041de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar dbgs() << " BB#" << R.first->getNumber() << " { " << R.second << "}\n"; 2042de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 2043de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar }); 2044de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 2045de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // When a slot is loaded from in a block without being stored to in the 2046de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // same block, it is live-on-entry to this block. To avoid CFG analysis, 2047de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // consider this slot to be live-on-exit from all blocks. 2048de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SmallSet<int,4> LoxFIs; 2049de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 2050de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar std::map<MachineBasicBlock*,std::vector<int>> BlockFIMap; 2051de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 2052de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &P : FIRangeMap) { 2053de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // P = pair(FI, map: BB->RangeList) 2054de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (BadFIs.count(P.first)) 2055de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar continue; 2056de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &B : MF) { 2057de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto F = P.second.Map.find(&B); 2058de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // F = pair(BB, RangeList) 2059de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (F == P.second.Map.end() || F->second.empty()) 2060de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar continue; 2061de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar HexagonBlockRanges::IndexRange &IR = F->second.front(); 2062de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (IR.start() == IndexType::Entry) 2063de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar LoxFIs.insert(P.first); 2064de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BlockFIMap[&B].push_back(P.first); 2065de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 2066de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 2067de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 2068de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DEBUG({ 2069de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar dbgs() << "Block-to-FI map (* -- live-on-exit):\n"; 2070de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &P : BlockFIMap) { 2071de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &FIs = P.second; 2072de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (FIs.empty()) 2073de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar continue; 2074de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar dbgs() << " BB#" << P.first->getNumber() << ": {"; 2075de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto I : FIs) { 2076de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar dbgs() << " fi#" << I; 2077de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (LoxFIs.count(I)) 2078de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar dbgs() << '*'; 2079de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 2080de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar dbgs() << " }\n"; 2081de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 2082de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar }); 2083de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 2084de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // eliminate loads, when all loads eliminated, eliminate all stores. 2085de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &B : MF) { 2086de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto F = BlockIndexes.find(&B); 2087de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert(F != BlockIndexes.end()); 2088de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar HexagonBlockRanges::InstrIndexMap &IM = F->second; 2089de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar HexagonBlockRanges::RegToRangeMap LM = HBR.computeLiveMap(IM); 2090de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar HexagonBlockRanges::RegToRangeMap DM = HBR.computeDeadMap(IM, LM); 2091de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DEBUG(dbgs() << "BB#" << B.getNumber() << " dead map\n" 2092de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar << HexagonBlockRanges::PrintRangeMap(DM, HRI)); 2093de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 2094de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto FI : BlockFIMap[&B]) { 2095de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (BadFIs.count(FI)) 2096de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar continue; 2097de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DEBUG(dbgs() << "Working on fi#" << FI << '\n'); 2098de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar HexagonBlockRanges::RangeList &RL = FIRangeMap[FI].Map[&B]; 2099de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &Range : RL) { 2100de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DEBUG(dbgs() << "--Examining range:" << RL << '\n'); 2101de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!IndexType::isInstr(Range.start()) || 2102de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar !IndexType::isInstr(Range.end())) 2103de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar continue; 2104de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineInstr *SI = IM.getInstr(Range.start()); 2105de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineInstr *EI = IM.getInstr(Range.end()); 2106de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert(SI->mayStore() && "Unexpected start instruction"); 2107de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert(EI->mayLoad() && "Unexpected end instruction"); 2108de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineOperand &SrcOp = SI->getOperand(2); 2109de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 2110de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar HexagonBlockRanges::RegisterRef SrcRR = { SrcOp.getReg(), 2111de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SrcOp.getSubReg() }; 2112de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto *RC = getRegClass({SrcOp.getReg(), SrcOp.getSubReg()}); 2113de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // The this-> is needed to unconfuse MSVC. 2114de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned FoundR = this->findPhysReg(MF, Range, IM, DM, RC); 2115de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DEBUG(dbgs() << "Replacement reg:" << PrintReg(FoundR, &HRI) << '\n'); 2116de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (FoundR == 0) 2117de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar continue; 2118de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 2119de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Generate the copy-in: "FoundR = COPY SrcR" at the store location. 2120de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineBasicBlock::iterator StartIt = SI, NextIt; 2121de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineInstr *CopyIn = nullptr; 2122de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (SrcRR.Reg != FoundR || SrcRR.Sub != 0) { 2123de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const DebugLoc &DL = SI->getDebugLoc(); 2124de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar CopyIn = BuildMI(B, StartIt, DL, HII.get(TargetOpcode::COPY), FoundR) 2125de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addOperand(SrcOp); 2126de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 2127de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 2128de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ++StartIt; 2129de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Check if this is a last store and the FI is live-on-exit. 2130de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (LoxFIs.count(FI) && (&Range == &RL.back())) { 2131de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Update store's source register. 2132de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (unsigned SR = SrcOp.getSubReg()) 2133de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SrcOp.setReg(HRI.getSubReg(FoundR, SR)); 2134de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar else 2135de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SrcOp.setReg(FoundR); 2136de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SrcOp.setSubReg(0); 2137de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // We are keeping this register live. 2138de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SrcOp.setIsKill(false); 2139de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } else { 2140de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar B.erase(SI); 2141de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar IM.replaceInstr(SI, CopyIn); 2142de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 2143de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 2144de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto EndIt = std::next(MachineBasicBlock::iterator(EI)); 2145de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto It = StartIt; It != EndIt; It = NextIt) { 2146de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineInstr *MI = &*It; 2147de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar NextIt = std::next(It); 2148de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar int TFI; 2149de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!HII.isLoadFromStackSlot(*MI, TFI) || TFI != FI) 2150de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar continue; 2151de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned DstR = MI->getOperand(0).getReg(); 2152de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert(MI->getOperand(0).getSubReg() == 0); 2153de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachineInstr *CopyOut = nullptr; 2154de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (DstR != FoundR) { 2155de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DebugLoc DL = MI->getDebugLoc(); 2156de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned MemSize = (1U << (HII.getMemAccessSize(MI) - 1)); 2157de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert(HII.getAddrMode(MI) == HexagonII::BaseImmOffset); 2158de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned CopyOpc = TargetOpcode::COPY; 2159de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (HII.isSignExtendingLoad(*MI)) 2160de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar CopyOpc = (MemSize == 1) ? Hexagon::A2_sxtb : Hexagon::A2_sxth; 2161de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar else if (HII.isZeroExtendingLoad(*MI)) 2162de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar CopyOpc = (MemSize == 1) ? Hexagon::A2_zxtb : Hexagon::A2_zxth; 2163de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar CopyOut = BuildMI(B, It, DL, HII.get(CopyOpc), DstR) 2164de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar .addReg(FoundR, getKillRegState(MI == EI)); 2165de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 2166de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar IM.replaceInstr(MI, CopyOut); 2167de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar B.erase(It); 2168de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 2169de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 2170de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Update the dead map. 2171de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar HexagonBlockRanges::RegisterRef FoundRR = { FoundR, 0 }; 2172de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto RR : HexagonBlockRanges::expandToSubRegs(FoundRR, MRI, HRI)) 2173de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DM[RR].subtract(Range); 2174de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } // for Range in range list 2175de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 2176de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 2177de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 2178de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 2179de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 21806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid HexagonFrameLowering::expandAlloca(MachineInstr *AI, 21816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const HexagonInstrInfo &HII, unsigned SP, unsigned CF) const { 21826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineBasicBlock &MB = *AI->getParent(); 21836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DebugLoc DL = AI->getDebugLoc(); 21846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned A = AI->getOperand(2).getImm(); 21856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 21866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Have 21876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Rd = alloca Rs, #A 21886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // 21896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // If Rs and Rd are different registers, use this sequence: 21906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Rd = sub(r29, Rs) 21916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // r29 = sub(r29, Rs) 21926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Rd = and(Rd, #-A) ; if necessary 21936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // r29 = and(r29, #-A) ; if necessary 21946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Rd = add(Rd, #CF) ; CF size aligned to at most A 21956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // otherwise, do 21966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Rd = sub(r29, Rs) 21976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Rd = and(Rd, #-A) ; if necessary 21986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // r29 = Rd 21996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Rd = add(Rd, #CF) ; CF size aligned to at most A 22006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 22016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineOperand &RdOp = AI->getOperand(0); 22026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MachineOperand &RsOp = AI->getOperand(1); 22036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned Rd = RdOp.getReg(), Rs = RsOp.getReg(); 22046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 22056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Rd = sub(r29, Rs) 22066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar BuildMI(MB, AI, DL, HII.get(Hexagon::A2_sub), Rd) 22076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addReg(SP) 22086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addReg(Rs); 22096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Rs != Rd) { 22106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // r29 = sub(r29, Rs) 22116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar BuildMI(MB, AI, DL, HII.get(Hexagon::A2_sub), SP) 22126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addReg(SP) 22136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addReg(Rs); 22146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 22156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (A > 8) { 22166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Rd = and(Rd, #-A) 22176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar BuildMI(MB, AI, DL, HII.get(Hexagon::A2_andir), Rd) 22186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addReg(Rd) 22196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addImm(-int64_t(A)); 22206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Rs != Rd) 22216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar BuildMI(MB, AI, DL, HII.get(Hexagon::A2_andir), SP) 22226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addReg(SP) 22236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addImm(-int64_t(A)); 22246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 22256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Rs == Rd) { 22266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // r29 = Rd 22276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar BuildMI(MB, AI, DL, HII.get(TargetOpcode::COPY), SP) 22286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addReg(Rd); 22296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 22306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (CF > 0) { 22316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Rd = add(Rd, #CF) 22326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar BuildMI(MB, AI, DL, HII.get(Hexagon::A2_addi), Rd) 22336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addReg(Rd) 22346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addImm(CF); 2235700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } 2236700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky} 2237700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 22386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 22396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarbool HexagonFrameLowering::needsAligna(const MachineFunction &MF) const { 22406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MachineFrameInfo *MFI = MF.getFrameInfo(); 22416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!MFI->hasVarSizedObjects()) 22426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return false; 22436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned MaxA = MFI->getMaxAlignment(); 22446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (MaxA <= getStackAlignment()) 22456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return false; 22466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return true; 22476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} 22486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 22496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 2250f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarconst MachineInstr *HexagonFrameLowering::getAlignaInstr( 2251f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const MachineFunction &MF) const { 22526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (auto &B : MF) 22536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (auto &I : B) 22546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (I.getOpcode() == Hexagon::ALIGNA) 22556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return &I; 22566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return nullptr; 22576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} 22586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 22596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 2260de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar/// Adds all callee-saved registers as implicit uses or defs to the 2261de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar/// instruction. 2262de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid HexagonFrameLowering::addCalleeSaveRegistersAsImpOperand(MachineInstr *MI, 2263de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const CSIVect &CSI, bool IsDef, bool IsKill) const { 2264de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Add the callee-saved registers as implicit uses. 2265de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &R : CSI) 2266de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MI->addOperand(MachineOperand::CreateReg(R.getReg(), IsDef, true, IsKill)); 22676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} 22686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 22696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 22706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar/// Determine whether the callee-saved register saves and restores should 22716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar/// be generated via inline code. If this function returns "true", inline 22726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar/// code will be generated. If this function returns "false", additional 22736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar/// checks are performed, which may still lead to the inline code. 22746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarbool HexagonFrameLowering::shouldInlineCSR(MachineFunction &MF, 22756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const CSIVect &CSI) const { 22766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (MF.getInfo<HexagonMachineFunctionInfo>()->hasEHReturn()) 22776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return true; 22786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!isOptSize(MF) && !isMinSize(MF)) 22796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (MF.getTarget().getOptLevel() > CodeGenOpt::Default) 22806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return true; 22816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 22826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Check if CSI only has double registers, and if the registers form 22836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // a contiguous block starting from D8. 22846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar BitVector Regs(Hexagon::NUM_TARGET_REGS); 22856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (unsigned i = 0, n = CSI.size(); i < n; ++i) { 22866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned R = CSI[i].getReg(); 22876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!Hexagon::DoubleRegsRegClass.contains(R)) 22886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return true; 22896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Regs[R] = true; 22906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 22916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar int F = Regs.find_first(); 22926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (F != Hexagon::D8) 22936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return true; 22946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar while (F >= 0) { 22956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar int N = Regs.find_next(F); 22966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (N >= 0 && N != F+1) 22976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return true; 22986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar F = N; 22996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 23006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 23016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return false; 23026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} 23036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 23046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 23056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarbool HexagonFrameLowering::useSpillFunction(MachineFunction &MF, 23066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const CSIVect &CSI) const { 23076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (shouldInlineCSR(MF, CSI)) 23086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return false; 23096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned NumCSI = CSI.size(); 23106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (NumCSI <= 1) 23116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return false; 23126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 23136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned Threshold = isOptSize(MF) ? SpillFuncThresholdOs 23146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar : SpillFuncThreshold; 23156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return Threshold < NumCSI; 23166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} 23176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 23186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 23196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarbool HexagonFrameLowering::useRestoreFunction(MachineFunction &MF, 23206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const CSIVect &CSI) const { 23216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (shouldInlineCSR(MF, CSI)) 23226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return false; 2323de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // The restore functions do a bit more than just restoring registers. 2324de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // The non-returning versions will go back directly to the caller's 2325de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // caller, others will clean up the stack frame in preparation for 2326de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // a tail call. Using them can still save code size even if only one 2327de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // register is getting restores. Make the decision based on -Oz: 2328de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // using -Os will use inline restore for a single register. 2329de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (isMinSize(MF)) 2330de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return true; 23316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned NumCSI = CSI.size(); 2332de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (NumCSI <= 1) 2333de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return false; 2334de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 23356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned Threshold = isOptSize(MF) ? SpillFuncThresholdOs-1 23366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar : SpillFuncThreshold; 23376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return Threshold < NumCSI; 2338b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 2339