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