158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner//===-- PrologEpilogInserter.cpp - Insert Prolog/Epilog code in function --===//
2edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman//
3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//                     The LLVM Compiler Infrastructure
4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman//
8b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//===----------------------------------------------------------------------===//
958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner//
1058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner// This pass is responsible for finalizing the functions frame layout, saving
1158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner// callee saved registers, and for emitting prolog & epilog code for the
1258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner// function.
1358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner//
1458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner// This pass must be run after register allocation.  After this pass is
1558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner// executed, it is illegal to construct MO_FrameIndex operands.
1658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner//
17378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby// This pass provides an optional shrink wrapping variant of prolog/epilog
18378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby// insertion, enabled via --shrink-wrap. See ShrinkWrapping.cpp.
19ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby//
2058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner//===----------------------------------------------------------------------===//
2158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
223d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#define DEBUG_TYPE "pei"
23752c1df73949438ef6fa86a86363ee7091aa2532John Mosby#include "PrologEpilogInserter.h"
24d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/IndexedMap.h"
25d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/STLExtras.h"
26d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/SmallSet.h"
27d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/Statistic.h"
28ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby#include "llvm/CodeGen/MachineDominators.h"
29eb24db9727a7babe863d5afe70c7bda3a460da18Chris Lattner#include "llvm/CodeGen/MachineFrameInfo.h"
30d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineInstr.h"
31d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineLoopInfo.h"
3284bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner#include "llvm/CodeGen/MachineRegisterInfo.h"
3349dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng#include "llvm/CodeGen/RegisterScavenging.h"
340b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/InlineAsm.h"
353d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach#include "llvm/Support/CommandLine.h"
36a4f0b3a084d120cfc5b5bb06f64b222f5cb72740Chris Lattner#include "llvm/Support/Compiler.h"
373d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/Support/Debug.h"
38d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetFrameLowering.h"
39d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetInstrInfo.h"
40d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetMachine.h"
41d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetRegisterInfo.h"
42c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng#include <climits>
43ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby
4405d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattnerusing namespace llvm;
45d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
46378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosbychar PEI::ID = 0;
471dd8c8560d45d36a8e507cd014352f1d313f9f9eAndrew Trickchar &llvm::PrologEpilogCodeInserterID = PEI::ID;
48b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby
492ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_BEGIN(PEI, "prologepilog",
502ab36d350293c77fc8941ce1023e4899df7e3a82Owen Anderson                "Prologue/Epilogue Insertion", false, false)
512ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
522ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
5325600cf50df79a6e7f8365a3ca7e940592e8ca74Andrew TrickINITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
542ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_END(PEI, "prologepilog",
551dd8c8560d45d36a8e507cd014352f1d313f9f9eAndrew Trick                    "Prologue/Epilogue Insertion & Frame Finalization",
561dd8c8560d45d36a8e507cd014352f1d313f9f9eAndrew Trick                    false, false)
57b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby
58c52b3cced8aebbc665021ec6b8bcd0974c4ad7aeJim GrosbachSTATISTIC(NumVirtualFrameRegs, "Number of virtual frame regs encountered");
59c52b3cced8aebbc665021ec6b8bcd0974c4ad7aeJim GrosbachSTATISTIC(NumScavengedRegs, "Number of frame index regs scavenged");
60b10946a5a938a433ca4d7301b8b5ff5a8c11a7ffEvan ChengSTATISTIC(NumBytesStackSpace,
61b10946a5a938a433ca4d7301b8b5ff5a8c11a7ffEvan Cheng          "Number of bytes used for stack in all functions");
62c52b3cced8aebbc665021ec6b8bcd0974c4ad7aeJim Grosbach
63378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby/// runOnMachineFunction - Insert prolog/epilog code and replace abstract
64378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby/// frame indexes with appropriate references.
65b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby///
66378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosbybool PEI::runOnMachineFunction(MachineFunction &Fn) {
67c5ec8a78ea898087ad361e5b755f74a76150e5fdAnton Korobeynikov  const Function* F = Fn.getFunction();
68b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby  const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo();
6916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = Fn.getTarget().getFrameLowering();
7094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov
7119273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick  assert(!Fn.getRegInfo().getNumVirtRegs() && "Regalloc must assign all vregs");
7219273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick
73378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  RS = TRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : NULL;
7465c58daa8b8985d2116216043103009815a55e77Jim Grosbach  FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(Fn);
75378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby
76b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling  // Calculate the MaxCallFrameSize and AdjustsStack variables for the
77b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling  // function's frame information. Also eliminates call frame pseudo
78b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling  // instructions.
7933b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  calculateCallsInformation(Fn);
8033b350bf24be396a127c81af045468765731afc7Anton Korobeynikov
81378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  // Allow the target machine to make some adjustments to the function
82378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  // e.g. UsedPhysRegs before calculateCalleeSavedRegisters.
8394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov  TFI->processFunctionBeforeCalleeSavedScan(Fn, RS);
84378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby
8533b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  // Scan the function for modified callee saved registers and insert spill code
8633b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  // for any callee saved registers that are modified.
87378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  calculateCalleeSavedRegisters(Fn);
88378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby
89378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  // Determine placement of CSR spill/restore code:
905b02901e91a155feca84d7383c1e569aacd1739eJim Grosbach  //  - With shrink wrapping, place spills and restores to tightly
91378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  //    enclose regions in the Machine CFG of the function where
925b02901e91a155feca84d7383c1e569aacd1739eJim Grosbach  //    they are used.
935b02901e91a155feca84d7383c1e569aacd1739eJim Grosbach  //  - Without shink wrapping (default), place all spills in the
94378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  //    entry block, all restores in return blocks.
95378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  placeCSRSpillsAndRestores(Fn);
96378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby
97378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  // Add the code to save and restore the callee saved registers
98831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling  if (!F->getAttributes().hasAttribute(AttributeSet::FunctionIndex,
99831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling                                       Attribute::Naked))
100c5ec8a78ea898087ad361e5b755f74a76150e5fdAnton Korobeynikov    insertCSRSpillsAndRestores(Fn);
101378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby
102378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  // Allow the target machine to make final modifications to the function
103378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  // before the frame layout is finalized.
1043080d23fde4981835d8a7faf46c152441fadb11fHal Finkel  TFI->processFunctionBeforeFrameFinalized(Fn, RS);
105378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby
106378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  // Calculate actual frame offsets for all abstract stack objects...
107378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  calculateFrameObjectOffsets(Fn);
108378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby
109378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  // Add prolog and epilog code to the function.  This function is required
110378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  // to align the stack frame as necessary for any stack variables or
111b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling  // called functions.  Because of this, calculateCalleeSavedRegisters()
112b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling  // must be called before this function in order to set the AdjustsStack
113378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  // and MaxCallFrameSize variables.
114831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling  if (!F->getAttributes().hasAttribute(AttributeSet::FunctionIndex,
115831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling                                       Attribute::Naked))
116c5ec8a78ea898087ad361e5b755f74a76150e5fdAnton Korobeynikov    insertPrologEpilogCode(Fn);
117378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby
118378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  // Replace all MO_FrameIndex operands with physical register references
119378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  // and actual offsets.
120378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  //
121378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  replaceFrameIndices(Fn);
122b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby
1233d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach  // If register scavenging is needed, as we've enabled doing it as a
1243d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach  // post-pass, scavenge the virtual registers that frame index elimiation
1253d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach  // inserted.
1263d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach  if (TRI->requiresRegisterScavenging(Fn) && FrameIndexVirtualScavenging)
1273d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach    scavengeFrameVirtualRegs(Fn);
1283d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach
12919273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick  // Clear any vregs created by virtual scavenging.
13019273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick  Fn.getRegInfo().clearVirtRegs();
13119273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick
132378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  delete RS;
133378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  clearAllSets();
134b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby  return true;
135ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby}
136ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby
137b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling/// calculateCallsInformation - Calculate the MaxCallFrameSize and AdjustsStack
13833b350bf24be396a127c81af045468765731afc7Anton Korobeynikov/// variables for the function's frame information and eliminate call frame
13933b350bf24be396a127c81af045468765731afc7Anton Korobeynikov/// pseudo instructions.
14033b350bf24be396a127c81af045468765731afc7Anton Korobeynikovvoid PEI::calculateCallsInformation(MachineFunction &Fn) {
141d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng  const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo();
14216c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = Fn.getTarget().getFrameLowering();
1439e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman  MachineFrameInfo *MFI = Fn.getFrameInfo();
14458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
14533b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  unsigned MaxCallFrameSize = 0;
146b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling  bool AdjustsStack = MFI->adjustsStack();
14758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
14858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  // Get the function call frame set-up and tear-down instruction opcode
149d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng  int FrameSetupOpcode   = TII.getCallFrameSetupOpcode();
150d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng  int FrameDestroyOpcode = TII.getCallFrameDestroyOpcode();
15158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
15233b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  // Early exit for targets which have no call frame setup/destroy pseudo
15333b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  // instructions.
15433b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  if (FrameSetupOpcode == -1 && FrameDestroyOpcode == -1)
15558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner    return;
15658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
1575c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng  std::vector<MachineBasicBlock::iterator> FrameSDOps;
15858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB)
1595c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng    for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I)
160c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos      if (I->getOpcode() == FrameSetupOpcode ||
161d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner          I->getOpcode() == FrameDestroyOpcode) {
1622a82ef317c39ac436f80854c7ddbb06bfddeada1Chris Lattner        assert(I->getNumOperands() >= 1 && "Call Frame Setup/Destroy Pseudo"
163d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner               " instructions should have a single immediate argument!");
1649e3304900ff69c4920fea7369c9c36916c4a6a6aChris Lattner        unsigned Size = I->getOperand(0).getImm();
165d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner        if (Size > MaxCallFrameSize) MaxCallFrameSize = Size;
166b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling        AdjustsStack = true;
1675c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng        FrameSDOps.push_back(I);
168518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner      } else if (I->isInlineAsm()) {
169f1e309eb4862459a76445942ba4dafc433b6f317Dale Johannesen        // Some inline asm's need a stack frame, as indicated by operand 1.
170c36b7069b42bece963b7e6adf020353ce990ef76Evan Cheng        unsigned ExtraInfo = I->getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
171c36b7069b42bece963b7e6adf020353ce990ef76Evan Cheng        if (ExtraInfo & InlineAsm::Extra_IsAlignStack)
172f1e309eb4862459a76445942ba4dafc433b6f317Dale Johannesen          AdjustsStack = true;
17358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner      }
17458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
175b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling  MFI->setAdjustsStack(AdjustsStack);
1769e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman  MFI->setMaxCallFrameSize(MaxCallFrameSize);
1778e3347332120956538a6d882b02719e34b57f0cdEvan Cheng
178058a024eb7265239d527680b0a448cdb48102a46Bill Wendling  for (std::vector<MachineBasicBlock::iterator>::iterator
179058a024eb7265239d527680b0a448cdb48102a46Bill Wendling         i = FrameSDOps.begin(), e = FrameSDOps.end(); i != e; ++i) {
180058a024eb7265239d527680b0a448cdb48102a46Bill Wendling    MachineBasicBlock::iterator I = *i;
181058a024eb7265239d527680b0a448cdb48102a46Bill Wendling
182058a024eb7265239d527680b0a448cdb48102a46Bill Wendling    // If call frames are not being included as part of the stack frame, and
1834642ad3af1cf508ac320b9afd25b065f08b36574Jim Grosbach    // the target doesn't indicate otherwise, remove the call frame pseudos
1844642ad3af1cf508ac320b9afd25b065f08b36574Jim Grosbach    // here. The sub/add sp instruction pairs are still inserted, but we don't
1854642ad3af1cf508ac320b9afd25b065f08b36574Jim Grosbach    // need to track the SP adjustment for frame index elimination.
186d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov    if (TFI->canSimplifyCallFramePseudos(Fn))
187700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky      TFI->eliminateCallFramePseudoInstr(Fn, *I->getParent(), I);
1885c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng  }
18933b350bf24be396a127c81af045468765731afc7Anton Korobeynikov}
19033b350bf24be396a127c81af045468765731afc7Anton Korobeynikov
19133b350bf24be396a127c81af045468765731afc7Anton Korobeynikov
19233b350bf24be396a127c81af045468765731afc7Anton Korobeynikov/// calculateCalleeSavedRegisters - Scan the function for modified callee saved
19333b350bf24be396a127c81af045468765731afc7Anton Korobeynikov/// registers.
194831737d329a727f53a1fb0572f7b7a8127208881Bill Wendlingvoid PEI::calculateCalleeSavedRegisters(MachineFunction &F) {
195831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling  const TargetRegisterInfo *RegInfo = F.getTarget().getRegisterInfo();
196831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling  const TargetFrameLowering *TFI = F.getTarget().getFrameLowering();
197831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling  MachineFrameInfo *MFI = F.getFrameInfo();
19833b350bf24be396a127c81af045468765731afc7Anton Korobeynikov
19933b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  // Get the callee saved register list...
200831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling  const uint16_t *CSRegs = RegInfo->getCalleeSavedRegs(&F);
20133b350bf24be396a127c81af045468765731afc7Anton Korobeynikov
20233b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  // These are used to keep track the callee-save area. Initialize them.
20333b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  MinCSFrameIndex = INT_MAX;
20433b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  MaxCSFrameIndex = 0;
20533b350bf24be396a127c81af045468765731afc7Anton Korobeynikov
20633b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  // Early exit for targets which have no callee saved registers.
20733b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  if (CSRegs == 0 || CSRegs[0] == 0)
20833b350bf24be396a127c81af045468765731afc7Anton Korobeynikov    return;
20958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
2108c5358c93675b009ba2d57c3a5980f6bc58ba536Dale Johannesen  // In Naked functions we aren't going to save any registers.
211831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling  if (F.getFunction()->getAttributes().hasAttribute(AttributeSet::FunctionIndex,
212831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling                                                    Attribute::Naked))
2138c5358c93675b009ba2d57c3a5980f6bc58ba536Dale Johannesen    return;
2148c5358c93675b009ba2d57c3a5980f6bc58ba536Dale Johannesen
21508ede262a744f99429658fadb43662441bdcb42dJim Laskey  std::vector<CalleeSavedInfo> CSI;
21658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  for (unsigned i = 0; CSRegs[i]; ++i) {
21758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner    unsigned Reg = CSRegs[i];
218831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling    if (F.getRegInfo().isPhysRegUsed(Reg)) {
219058a024eb7265239d527680b0a448cdb48102a46Bill Wendling      // If the reg is modified, save it!
22042d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola      CSI.push_back(CalleeSavedInfo(Reg));
22173ff5120eb8b8c0ccbfed8a17f1024c67a75f319Alkis Evlogimenos    }
22258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  }
22358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
224f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey  if (CSI.empty())
225c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng    return;   // Early exit if no callee saved registers are modified!
22658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
227c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner  unsigned NumFixedSpillSlots;
22816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering::SpillSlot *FixedSpillSlots =
229ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng    TFI->getCalleeSavedSpillSlots(NumFixedSpillSlots);
230c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner
23158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  // Now that we know which registers need to be saved and restored, allocate
23258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  // stack slots for them.
233058a024eb7265239d527680b0a448cdb48102a46Bill Wendling  for (std::vector<CalleeSavedInfo>::iterator
234058a024eb7265239d527680b0a448cdb48102a46Bill Wendling         I = CSI.begin(), E = CSI.end(); I != E; ++I) {
235058a024eb7265239d527680b0a448cdb48102a46Bill Wendling    unsigned Reg = I->getReg();
23642d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola    const TargetRegisterClass *RC = RegInfo->getMinimalPhysRegClass(Reg);
237c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner
238910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng    int FrameIdx;
239831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling    if (RegInfo->hasReservedSpillSlot(F, Reg, FrameIdx)) {
240910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng      I->setFrameIdx(FrameIdx);
241910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng      continue;
242910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng    }
243910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng
244c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner    // Check to see if this physreg must be spilled to a particular stack slot
245c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner    // on this target.
24616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov    const TargetFrameLowering::SpillSlot *FixedSlot = FixedSpillSlots;
247c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner    while (FixedSlot != FixedSpillSlots+NumFixedSpillSlots &&
2488ff95de83cbe85d939535d2f4fb5f9b2b721081aTilmann Scheller           FixedSlot->Reg != Reg)
249c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner      ++FixedSlot;
250c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner
251058a024eb7265239d527680b0a448cdb48102a46Bill Wendling    if (FixedSlot == FixedSpillSlots + NumFixedSpillSlots) {
252c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner      // Nope, just spill it anywhere convenient.
2535feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng      unsigned Align = RC->getAlignment();
2545feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng      unsigned StackAlign = TFI->getStackAlignment();
255058a024eb7265239d527680b0a448cdb48102a46Bill Wendling
256058a024eb7265239d527680b0a448cdb48102a46Bill Wendling      // We may not be able to satisfy the desired alignment specification of
257058a024eb7265239d527680b0a448cdb48102a46Bill Wendling      // the TargetRegisterClass if the stack alignment is smaller. Use the
258058a024eb7265239d527680b0a448cdb48102a46Bill Wendling      // min.
2595feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng      Align = std::min(Align, StackAlign);
2609e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman      FrameIdx = MFI->CreateStackObject(RC->getSize(), Align, true);
261c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng      if ((unsigned)FrameIdx < MinCSFrameIndex) MinCSFrameIndex = FrameIdx;
262c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng      if ((unsigned)FrameIdx > MaxCSFrameIndex) MaxCSFrameIndex = FrameIdx;
263c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner    } else {
264c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner      // Spill it to the stack where we must.
265ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng      FrameIdx = MFI->CreateFixedObject(RC->getSize(), FixedSlot->Offset, true);
266c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner    }
267058a024eb7265239d527680b0a448cdb48102a46Bill Wendling
268058a024eb7265239d527680b0a448cdb48102a46Bill Wendling    I->setFrameIdx(FrameIdx);
26958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  }
27008ede262a744f99429658fadb43662441bdcb42dJim Laskey
2719e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman  MFI->setCalleeSavedInfo(CSI);
272c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner}
273c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner
274ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby/// insertCSRSpillsAndRestores - Insert spill and restore code for
275ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby/// callee saved registers used in the function, handling shrink wrapping.
276c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner///
277ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosbyvoid PEI::insertCSRSpillsAndRestores(MachineFunction &Fn) {
278f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey  // Get callee saved register information.
2799e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman  MachineFrameInfo *MFI = Fn.getFrameInfo();
2809e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman  const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
281ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby
2829e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman  MFI->setCalleeSavedInfoValid(true);
283d62c9a697b53f9e754926a89126fd121220ed09bJakob Stoklund Olesen
284c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng  // Early exit if no callee saved registers are modified!
285f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey  if (CSI.empty())
286edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman    return;
287c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner
288f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson  const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo();
28916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = Fn.getTarget().getFrameLowering();
290746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng  const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo();
291ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby  MachineBasicBlock::iterator I;
29200dff8dda29b5a249cd99405ce26e84cef13ba53Evan Cheng
29306a23ea8083657270e86a178abf050246caac0b5Chad Rosier  if (!ShrinkWrapThisFunction) {
294b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    // Spill using target interface.
295b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    I = EntryBlock->begin();
296cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov    if (!TFI->spillCalleeSavedRegisters(*EntryBlock, I, CSI, TRI)) {
297b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
298ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby        // Add the callee-saved register as live-in.
299ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby        // It's killed at the spill.
300b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby        EntryBlock->addLiveIn(CSI[i].getReg());
301ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby
302ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby        // Insert the spill to the stack frame.
30342d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola        unsigned Reg = CSI[i].getReg();
30442d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola        const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
30542d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola        TII.storeRegToStackSlot(*EntryBlock, I, Reg, true,
30642d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola                                CSI[i].getFrameIdx(), RC, TRI);
307ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby      }
308ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng    }
309ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby
310b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    // Restore using target interface.
311b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    for (unsigned ri = 0, re = ReturnBlocks.size(); ri != re; ++ri) {
312b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      MachineBasicBlock* MBB = ReturnBlocks[ri];
313c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos      I = MBB->end(); --I;
31458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
315f7c094000f4baf094b1d60ba68a5b4e0193c502aBill Wendling      // Skip over all terminator instructions, which are part of the return
3164fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner      // sequence.
3174fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner      MachineBasicBlock::iterator I2 = I;
3185a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng      while (I2 != MBB->begin() && (--I2)->isTerminator())
3194fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner        I = I2;
3204fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner
321dfd58709cc78e841ef4a50ba75d940473031617eChris Lattner      bool AtStart = I == MBB->begin();
322ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner      MachineBasicBlock::iterator BeforeI = I;
323ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner      if (!AtStart)
324ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner        --BeforeI;
325ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby
326ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby      // Restore all registers immediately before the return and any
3277a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner      // terminators that precede it.
328cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov      if (!TFI->restoreCalleeSavedRegisters(*MBB, I, CSI, TRI)) {
329ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng        for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
33042d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola          unsigned Reg = CSI[i].getReg();
33142d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola          const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
33242d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola          TII.loadRegFromStackSlot(*MBB, I, Reg,
333ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby                                   CSI[i].getFrameIdx(),
33442d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola                                   RC, TRI);
335ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng          assert(I != MBB->begin() &&
336ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng                 "loadRegFromStackSlot didn't insert any code!");
337ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby          // Insert in reverse order.  loadRegFromStackSlot can insert
338ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby          // multiple instructions.
339ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng          if (AtStart)
340ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng            I = MBB->begin();
341ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng          else {
342ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng            I = BeforeI;
343ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng            ++I;
344ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng          }
345ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner        }
34658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner      }
347b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    }
348b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    return;
349b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby  }
350ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby
351b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby  // Insert spills.
352b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby  std::vector<CalleeSavedInfo> blockCSI;
353b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby  for (CSRegBlockMap::iterator BI = CSRSave.begin(),
354b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby         BE = CSRSave.end(); BI != BE; ++BI) {
355b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    MachineBasicBlock* MBB = BI->first;
356b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    CSRegSet save = BI->second;
357ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby
358b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    if (save.empty())
359b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      continue;
360ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby
361b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    blockCSI.clear();
362b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    for (CSRegSet::iterator RI = save.begin(),
363b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby           RE = save.end(); RI != RE; ++RI) {
364b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      blockCSI.push_back(CSI[*RI]);
365b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    }
366b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    assert(blockCSI.size() > 0 &&
367b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby           "Could not collect callee saved register info");
368b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby
369b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    I = MBB->begin();
370b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby
371b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    // When shrink wrapping, use stack slot stores/loads.
372b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    for (unsigned i = 0, e = blockCSI.size(); i != e; ++i) {
373b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      // Add the callee-saved register as live-in.
374b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      // It's killed at the spill.
375b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      MBB->addLiveIn(blockCSI[i].getReg());
376b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby
377b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      // Insert the spill to the stack frame.
37842d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola      unsigned Reg = blockCSI[i].getReg();
37942d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola      const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
38042d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola      TII.storeRegToStackSlot(*MBB, I, Reg,
381b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby                              true,
382b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby                              blockCSI[i].getFrameIdx(),
38342d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola                              RC, TRI);
384b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    }
385b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby  }
386b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby
387b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby  for (CSRegBlockMap::iterator BI = CSRRestore.begin(),
388b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby         BE = CSRRestore.end(); BI != BE; ++BI) {
389b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    MachineBasicBlock* MBB = BI->first;
390b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    CSRegSet restore = BI->second;
391b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby
392b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    if (restore.empty())
393b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      continue;
394b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby
395b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    blockCSI.clear();
396b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    for (CSRegSet::iterator RI = restore.begin(),
397b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby           RE = restore.end(); RI != RE; ++RI) {
398b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      blockCSI.push_back(CSI[*RI]);
399b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    }
400b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    assert(blockCSI.size() > 0 &&
401b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby           "Could not find callee saved register info");
402b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby
403b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    // If MBB is empty and needs restores, insert at the _beginning_.
404b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    if (MBB->empty()) {
405b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      I = MBB->begin();
406b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    } else {
407b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      I = MBB->end();
408b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      --I;
409b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby
410b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      // Skip over all terminator instructions, which are part of the
411b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      // return sequence.
4125a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng      if (! I->isTerminator()) {
413b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby        ++I;
414ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby      } else {
415b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby        MachineBasicBlock::iterator I2 = I;
4165a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng        while (I2 != MBB->begin() && (--I2)->isTerminator())
417b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby          I = I2;
418ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby      }
419b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    }
420ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby
421b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    bool AtStart = I == MBB->begin();
422b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    MachineBasicBlock::iterator BeforeI = I;
423b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    if (!AtStart)
424b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      --BeforeI;
425b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby
426b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    // Restore all registers immediately before the return and any
4277a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner    // terminators that precede it.
428b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    for (unsigned i = 0, e = blockCSI.size(); i != e; ++i) {
42942d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola      unsigned Reg = blockCSI[i].getReg();
43042d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola      const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
43142d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola      TII.loadRegFromStackSlot(*MBB, I, Reg,
432b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby                               blockCSI[i].getFrameIdx(),
43342d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola                               RC, TRI);
434b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      assert(I != MBB->begin() &&
435b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby             "loadRegFromStackSlot didn't insert any code!");
436b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      // Insert in reverse order.  loadRegFromStackSlot can insert
437b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      // multiple instructions.
438b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      if (AtStart)
439b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby        I = MBB->begin();
440b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      else {
441b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby        I = BeforeI;
442b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby        ++I;
443ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby      }
44458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner    }
445ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby  }
44658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner}
44758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
448cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling/// AdjustStackOffset - Helper function used to adjust the stack frame offset.
449cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendlingstatic inline void
4509e9aa44d1a33fb845268ba07b726a31f26195690Dan GohmanAdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx,
451cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling                  bool StackGrowsDown, int64_t &Offset,
452cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling                  unsigned &MaxAlign) {
45394188d4e67cf1c570ad87dbabf198931033d628eBob Wilson  // If the stack grows down, add the object size to find the lowest address.
454cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling  if (StackGrowsDown)
4559e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman    Offset += MFI->getObjectSize(FrameIdx);
456cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling
4579e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman  unsigned Align = MFI->getObjectAlignment(FrameIdx);
458cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling
459cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling  // If the alignment of this object is greater than that of the stack, then
460cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling  // increase the stack alignment to match.
461cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling  MaxAlign = std::max(MaxAlign, Align);
462cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling
463cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling  // Adjust to alignment boundary.
464cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling  Offset = (Offset + Align - 1) / Align * Align;
465cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling
466cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling  if (StackGrowsDown) {
4673d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach    DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << -Offset << "]\n");
4689e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman    MFI->setObjectOffset(FrameIdx, -Offset); // Set the computed offset
469cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling  } else {
4703d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach    DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << Offset << "]\n");
4719e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman    MFI->setObjectOffset(FrameIdx, Offset);
4729e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman    Offset += MFI->getObjectSize(FrameIdx);
473cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling  }
474cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling}
47558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
47658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the
47792b9fcea7b3180ed18f379212d14bd5cea7a1954Chris Lattner/// abstract stack objects.
47858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner///
47958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattnervoid PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
48016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering &TFI = *Fn.getTarget().getFrameLowering();
481edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman
48258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  bool StackGrowsDown =
48316c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov    TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown;
484edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman
48558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  // Loop over all of the stack objects, assigning sequential addresses...
4869e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman  MachineFrameInfo *MFI = Fn.getFrameInfo();
48758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
48805d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner  // Start at the beginning of the local area.
489577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner  // The Offset is the distance from the stack top in the direction
490c0d6012b31afa2220306afa27db1b02e18427776Dan Gohman  // of stack growth -- so it's always nonnegative.
491c34666ee1871d47dfa4865c7138902dd1b770101Bob Wilson  int LocalAreaOffset = TFI.getOffsetOfLocalArea();
492577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner  if (StackGrowsDown)
493c34666ee1871d47dfa4865c7138902dd1b770101Bob Wilson    LocalAreaOffset = -LocalAreaOffset;
494c34666ee1871d47dfa4865c7138902dd1b770101Bob Wilson  assert(LocalAreaOffset >= 0
495577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner         && "Local area offset should be in direction of stack growth");
496c34666ee1871d47dfa4865c7138902dd1b770101Bob Wilson  int64_t Offset = LocalAreaOffset;
497577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner
498577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner  // If there are fixed sized objects that are preallocated in the local area,
499577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner  // non-fixed objects can't be allocated right at the start of local area.
500ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby  // We currently don't support filling in holes in between fixed sized
501ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby  // objects, so we adjust 'Offset' to point to the end of last fixed sized
50205d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner  // preallocated object.
5039e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman  for (int i = MFI->getObjectIndexBegin(); i != 0; ++i) {
504a401b1e1c5eb9563617db8a2477b4c5f8b239521Chris Lattner    int64_t FixedOff;
505577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner    if (StackGrowsDown) {
506577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner      // The maximum distance from the stack pointer is at lower address of
507577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner      // the object -- which is given by offset. For down growing stack
508577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner      // the offset is negative, so we negate the offset to get the distance.
5099e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman      FixedOff = -MFI->getObjectOffset(i);
510577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner    } else {
511edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman      // The maximum distance from the start pointer is at the upper
512577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner      // address of the object.
5139e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman      FixedOff = MFI->getObjectOffset(i) + MFI->getObjectSize(i);
514edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman    }
515edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman    if (FixedOff > Offset) Offset = FixedOff;
51605d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner  }
51705d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner
518c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng  // First assign frame offsets to stack objects that are used to spill
519ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng  // callee saved registers.
520c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng  if (StackGrowsDown) {
5215c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng    for (unsigned i = MinCSFrameIndex; i <= MaxCSFrameIndex; ++i) {
522b4c14aaa50b58ac723d0ed179695e1cd7296572aEric Christopher      // If the stack grows down, we need to add the size to find the lowest
523c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng      // address of the object.
5249e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman      Offset += MFI->getObjectSize(i);
525c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng
5269e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman      unsigned Align = MFI->getObjectAlignment(i);
527c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng      // Adjust to alignment boundary
528c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng      Offset = (Offset+Align-1)/Align*Align;
529c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng
5309e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman      MFI->setObjectOffset(i, -Offset);        // Set the computed offset
531c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng    }
532c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng  } else {
533a8c63f0fc9feb48f17d702a907f065959c41e337Bruno Cardoso Lopes    int MaxCSFI = MaxCSFrameIndex, MinCSFI = MinCSFrameIndex;
534a8c63f0fc9feb48f17d702a907f065959c41e337Bruno Cardoso Lopes    for (int i = MaxCSFI; i >= MinCSFI ; --i) {
5359e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman      unsigned Align = MFI->getObjectAlignment(i);
536c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng      // Adjust to alignment boundary
537c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng      Offset = (Offset+Align-1)/Align*Align;
538c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng
5399e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman      MFI->setObjectOffset(i, Offset);
5409e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman      Offset += MFI->getObjectSize(i);
541c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng    }
542c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng  }
543c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng
5449e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman  unsigned MaxAlign = MFI->getMaxAlignment();
5457545f49a5edfe19612d03e683d8b955c03018056Evan Cheng
54687f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng  // Make sure the special register scavenging spill slot is closest to the
54787f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng  // frame pointer if a frame pointer is required.
5486f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman  const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo();
5490f657b156f3d0890584bedda7294932a20b2ea16Jim Grosbach  if (RS && TFI.hasFP(Fn) && RegInfo->useFPForScavengingIndex(Fn) &&
5500f657b156f3d0890584bedda7294932a20b2ea16Jim Grosbach      !RegInfo->needsStackRealignment(Fn)) {
55187f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng    int SFI = RS->getScavengingFrameIndex();
552cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling    if (SFI >= 0)
5539e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman      AdjustStackOffset(MFI, SFI, StackGrowsDown, Offset, MaxAlign);
55487f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng  }
55587f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng
5564861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach  // FIXME: Once this is working, then enable flag will change to a target
5574861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach  // check for whether the frame is large enough to want to use virtual
5584861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach  // frame index registers. Functions which don't want/need this optimization
5594861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach  // will continue to use the existing code path.
560a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach  if (MFI->getUseLocalStackAllocationBlock()) {
5614861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach    unsigned Align = MFI->getLocalFrameMaxAlign();
5624861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach
5634861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach    // Adjust to alignment boundary.
5644861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach    Offset = (Offset + Align - 1) / Align * Align;
5654861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach
566fecdea0bf77599038eb368db3bc6a38a14900308Jim Grosbach    DEBUG(dbgs() << "Local frame base offset: " << Offset << "\n");
567fecdea0bf77599038eb368db3bc6a38a14900308Jim Grosbach
5683d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach    // Resolve offsets for objects in the local block.
5693d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach    for (unsigned i = 0, e = MFI->getLocalFrameObjectCount(); i != e; ++i) {
5703d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach      std::pair<int, int64_t> Entry = MFI->getLocalFrameObjectMap(i);
57167ff81a08319f916571cea90ed92e17015c8584fJim Grosbach      int64_t FIOffset = (StackGrowsDown ? -Offset : Offset) + Entry.second;
57267ff81a08319f916571cea90ed92e17015c8584fJim Grosbach      DEBUG(dbgs() << "alloc FI(" << Entry.first << ") at SP[" <<
57367ff81a08319f916571cea90ed92e17015c8584fJim Grosbach            FIOffset << "]\n");
57467ff81a08319f916571cea90ed92e17015c8584fJim Grosbach      MFI->setObjectOffset(Entry.first, FIOffset);
5753d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach    }
57667ff81a08319f916571cea90ed92e17015c8584fJim Grosbach    // Allocate the local block
57767ff81a08319f916571cea90ed92e17015c8584fJim Grosbach    Offset += MFI->getLocalFrameSize();
57867ff81a08319f916571cea90ed92e17015c8584fJim Grosbach
57967ff81a08319f916571cea90ed92e17015c8584fJim Grosbach    MaxAlign = std::max(Align, MaxAlign);
5803d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach  }
5813d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach
582b2a4298ce41e7ef80cd75a3c1dfa6433f0759a1aBill Wendling  // Make sure that the stack protector comes before the local variables on the
583b2a4298ce41e7ef80cd75a3c1dfa6433f0759a1aBill Wendling  // stack.
584dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling  SmallSet<int, 16> LargeStackObjs;
585dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling  if (MFI->getStackProtectorIndex() >= 0) {
5869e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman    AdjustStackOffset(MFI, MFI->getStackProtectorIndex(), StackGrowsDown,
587cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling                      Offset, MaxAlign);
588b2a4298ce41e7ef80cd75a3c1dfa6433f0759a1aBill Wendling
589dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling    // Assign large stack objects first.
590dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling    for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) {
591a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach      if (MFI->isObjectPreAllocated(i) &&
592a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach          MFI->getUseLocalStackAllocationBlock())
5933d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach        continue;
594dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling      if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex)
595dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling        continue;
596dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling      if (RS && (int)i == RS->getScavengingFrameIndex())
597dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling        continue;
598dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling      if (MFI->isDeadObjectIndex(i))
599dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling        continue;
600dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling      if (MFI->getStackProtectorIndex() == (int)i)
601dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling        continue;
602dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling      if (!MFI->MayNeedStackProtector(i))
603dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling        continue;
604dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling
605dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling      AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign);
606dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling      LargeStackObjs.insert(i);
607dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling    }
608dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling  }
609dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling
610c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng  // Then assign frame offsets to stack objects that are not used to spill
611ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng  // callee saved registers.
6129e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman  for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) {
613a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach    if (MFI->isObjectPreAllocated(i) &&
614a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach        MFI->getUseLocalStackAllocationBlock())
6153d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach      continue;
616c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng    if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex)
617c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng      continue;
61887f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng    if (RS && (int)i == RS->getScavengingFrameIndex())
61987f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng      continue;
6209e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman    if (MFI->isDeadObjectIndex(i))
621d36531249a9a9500e516148e7e72d4c0a7a4d0eeEvan Cheng      continue;
6229e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman    if (MFI->getStackProtectorIndex() == (int)i)
62344cf38c01ff610139d2e8dbbdc4e6123a3debcddBill Wendling      continue;
624dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling    if (LargeStackObjs.count(i))
625dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling      continue;
626c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng
6279e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman    AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign);
62858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  }
62958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
63087f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng  // Make sure the special register scavenging spill slot is closest to the
63187f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng  // stack pointer.
6320f657b156f3d0890584bedda7294932a20b2ea16Jim Grosbach  if (RS && (!TFI.hasFP(Fn) || RegInfo->needsStackRealignment(Fn) ||
6330f657b156f3d0890584bedda7294932a20b2ea16Jim Grosbach             !RegInfo->useFPForScavengingIndex(Fn))) {
63487f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng    int SFI = RS->getScavengingFrameIndex();
635cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling    if (SFI >= 0)
6369e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman      AdjustStackOffset(MFI, SFI, StackGrowsDown, Offset, MaxAlign);
63787f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng  }
63887f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng
63933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  if (!TFI.targetHandlesStackFrameRounding()) {
6405c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng    // If we have reserved argument space for call sites in the function
6415c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng    // immediately on entry to the current function, count it as part of the
6425c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng    // overall stack size.
643d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov    if (MFI->adjustsStack() && TFI.hasReservedCallFrame(Fn))
6449e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman      Offset += MFI->getMaxCallFrameSize();
645367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng
6460035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson    // Round up the size to a multiple of the alignment.  If the function has
6470035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson    // any calls or alloca's, align to the target's StackAlignment value to
6480035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson    // ensure that the callee's frame or the alloca data is suitably aligned;
6490035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson    // otherwise, for leaf functions, align to the TransientStackAlignment
6500035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson    // value.
6510035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson    unsigned StackAlign;
652b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling    if (MFI->adjustsStack() || MFI->hasVarSizedObjects() ||
6539e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman        (RegInfo->needsStackRealignment(Fn) && MFI->getObjectIndexEnd() != 0))
6540035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson      StackAlign = TFI.getStackAlignment();
6550035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson    else
6560035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson      StackAlign = TFI.getTransientStackAlignment();
657b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling
658b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling    // If the frame pointer is eliminated, all frame offsets will be relative to
659b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling    // SP not FP. Align to MaxAlign so this works.
6600035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson    StackAlign = std::max(StackAlign, MaxAlign);
6610035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson    unsigned AlignMask = StackAlign - 1;
662ea84c5ee952c62dd0c703c9852d7a60715e4a435Chris Lattner    Offset = (Offset + AlignMask) & ~uint64_t(AlignMask);
663367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng  }
664367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng
665367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng  // Update frame info to pretend that this is part of the stack...
666c219d191aadb4f9532bcaea5c5e66f66912656caJakob Stoklund Olesen  int64_t StackSize = Offset - LocalAreaOffset;
667c219d191aadb4f9532bcaea5c5e66f66912656caJakob Stoklund Olesen  MFI->setStackSize(StackSize);
668c219d191aadb4f9532bcaea5c5e66f66912656caJakob Stoklund Olesen  NumBytesStackSpace += StackSize;
6694ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner}
6704ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner
671c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng/// insertPrologEpilogCode - Scan the function for modified callee saved
672c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng/// registers, insert spill code for these callee saved registers, then add
6734ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner/// prolog and epilog code to the function.
6744ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner///
6754ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattnervoid PEI::insertPrologEpilogCode(MachineFunction &Fn) {
67616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering &TFI = *Fn.getTarget().getFrameLowering();
677874384e20f618d6ac932628db64e048757213fcdAnton Korobeynikov
6784ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner  // Add prologue to the function...
67933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  TFI.emitPrologue(Fn);
6804ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner
6814ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner  // Add epilogue to restore the callee-save registers in each exiting block
6824ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner  for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) {
6834ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner    // If last instruction is a return instruction, add an epilogue
6845a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng    if (!I->empty() && I->back().isReturn())
68533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov      TFI.emitEpilogue(Fn, *I);
6864ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner  }
68776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola
688e81abfd30b7c81735e9f3d79006c2653690aa592Rafael Espindola  // Emit additional code that is required to support segmented stacks, if
689e81abfd30b7c81735e9f3d79006c2653690aa592Rafael Espindola  // we've been asked for it.  This, when linked with a runtime with support
690e81abfd30b7c81735e9f3d79006c2653690aa592Rafael Espindola  // for segmented stacks (libgcc is one), will result in allocating stack
691e81abfd30b7c81735e9f3d79006c2653690aa592Rafael Espindola  // space in small chunks instead of one large contiguous block.
6928a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky  if (Fn.getTarget().Options.EnableSegmentedStacks)
69376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola    TFI.adjustForSegmentedStacks(Fn);
69498fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer
69598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer  // Emit additional code that is required to explicitly handle the stack in
69698fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer  // HiPE native code (if needed) when loaded in the Erlang/OTP runtime. The
69798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer  // approach is rather similar to that of Segmented Stacks, but it uses a
69898fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer  // different conditional check and another BIF for allocating more stack
69998fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer  // space.
70098fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer  if (Fn.getFunction()->getCallingConv() == CallingConv::HiPE)
70198fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer    TFI.adjustForHiPEPrologue(Fn);
70258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner}
70358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
70458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// replaceFrameIndices - Replace all MO_FrameIndex operands with physical
70558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// register references and actual offsets.
70658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner///
70758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattnervoid PEI::replaceFrameIndices(MachineFunction &Fn) {
70858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  if (!Fn.getFrameInfo()->hasStackObjects()) return; // Nothing to do?
70958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
71058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  const TargetMachine &TM = Fn.getTarget();
71158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  assert(TM.getRegisterInfo() && "TM::getRegisterInfo() must be implemented!");
712d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng  const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo();
7136f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman  const TargetRegisterInfo &TRI = *TM.getRegisterInfo();
71416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = TM.getFrameLowering();
7158e3347332120956538a6d882b02719e34b57f0cdEvan Cheng  bool StackGrowsDown =
71616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov    TFI->getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown;
717d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng  int FrameSetupOpcode   = TII.getCallFrameSetupOpcode();
718d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng  int FrameDestroyOpcode = TII.getCallFrameDestroyOpcode();
71958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
720ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby  for (MachineFunction::iterator BB = Fn.begin(),
721ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby         E = Fn.end(); BB != E; ++BB) {
7226627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach#ifndef NDEBUG
7236627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach    int SPAdjCount = 0; // frame setup / destroy count.
7246627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach#endif
7258e3347332120956538a6d882b02719e34b57f0cdEvan Cheng    int SPAdj = 0;  // SP offset due to call frame setup / destroy.
7263d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach    if (RS && !FrameIndexVirtualScavenging) RS->enterBasicBlock(BB);
727ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby
7280ebe9c132c6b9c74b334f0c7503e702b499575d5Chris Lattner    for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) {
729405abffd5eb1ad1841491e51943b598c935f309bBill Wendling
730405abffd5eb1ad1841491e51943b598c935f309bBill Wendling      if (I->getOpcode() == FrameSetupOpcode ||
731405abffd5eb1ad1841491e51943b598c935f309bBill Wendling          I->getOpcode() == FrameDestroyOpcode) {
7326627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach#ifndef NDEBUG
7336627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach        // Track whether we see even pairs of them
7346627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach        SPAdjCount += I->getOpcode() == FrameSetupOpcode ? 1 : -1;
7356627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach#endif
736405abffd5eb1ad1841491e51943b598c935f309bBill Wendling        // Remember how much SP has been adjusted to create the call
737405abffd5eb1ad1841491e51943b598c935f309bBill Wendling        // frame.
73871a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner        int Size = I->getOperand(0).getImm();
739405abffd5eb1ad1841491e51943b598c935f309bBill Wendling
74071a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner        if ((!StackGrowsDown && I->getOpcode() == FrameSetupOpcode) ||
74171a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner            (StackGrowsDown && I->getOpcode() == FrameDestroyOpcode))
74271a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner          Size = -Size;
743988a5782d3ce3cddc65d57d6aac7312d33ed59abBill Wendling
74471a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner        SPAdj += Size;
745405abffd5eb1ad1841491e51943b598c935f309bBill Wendling
7465e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner        MachineBasicBlock::iterator PrevI = BB->end();
7475e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner        if (I != BB->begin()) PrevI = prior(I);
748700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky        TFI->eliminateCallFramePseudoInstr(Fn, *BB, I);
749405abffd5eb1ad1841491e51943b598c935f309bBill Wendling
75071a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner        // Visit the instructions created by eliminateCallFramePseudoInstr().
7515e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner        if (PrevI == BB->end())
7525e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner          I = BB->begin();     // The replaced instr was the first in the block.
7535e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner        else
7547896c9f436a4eda5ec15e882a7505ba482a2fcd0Chris Lattner          I = llvm::next(PrevI);
75571a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner        continue;
7568e3347332120956538a6d882b02719e34b57f0cdEvan Cheng      }
757988a5782d3ce3cddc65d57d6aac7312d33ed59abBill Wendling
75878a5bd5dbd4d99d916c69d89ceaabd83c0e52469Evan Cheng      MachineInstr *MI = I;
759405abffd5eb1ad1841491e51943b598c935f309bBill Wendling      bool DoIncr = true;
7603ab115ce8f5262608630d67c28707dbd24361d03Chad Rosier      for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
7615fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier        if (!MI->getOperand(i).isFI())
7625fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier            continue;
7635fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier
7645fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier        // Some instructions (e.g. inline asm instructions) can have
7655fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier        // multiple frame indices and/or cause eliminateFrameIndex
7665fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier        // to insert more than one instruction. We need the register
7675fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier        // scavenger to go through all of these instructions so that
7685fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier        // it can update its register information. We keep the
7695fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier        // iterator at the point before insertion so that we can
7705fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier        // revisit them in full.
7715fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier        bool AtBeginning = (I == BB->begin());
7725fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier        if (!AtBeginning) --I;
7735fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier
7745fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier        // If this instruction has a FrameIndex operand, we need to
7755fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier        // use that target machine register info object to eliminate
7765fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier        // it.
7775fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier        TRI.eliminateFrameIndex(MI, SPAdj, i,
7785fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier                                FrameIndexVirtualScavenging ?  NULL : RS);
7795fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier
7805fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier        // Reset the iterator if we were at the beginning of the BB.
7815fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier        if (AtBeginning) {
7825fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier          I = BB->begin();
7835fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier          DoIncr = false;
78471a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner        }
7855fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier
7865fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier        MI = 0;
7875fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier        break;
7883ab115ce8f5262608630d67c28707dbd24361d03Chad Rosier      }
789405abffd5eb1ad1841491e51943b598c935f309bBill Wendling
7908fc2d0ee8dd4e077ee90a1fcc36fd0101c2947a2Chris Lattner      if (DoIncr && I != BB->end()) ++I;
791405abffd5eb1ad1841491e51943b598c935f309bBill Wendling
79249dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng      // Update register states.
7933d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach      if (RS && !FrameIndexVirtualScavenging && MI) RS->forward(MI);
79449dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng    }
795988a5782d3ce3cddc65d57d6aac7312d33ed59abBill Wendling
7966627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach    // If we have evenly matched pairs of frame setup / destroy instructions,
7976627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach    // make sure the adjustments come out to zero. If we don't have matched
7986627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach    // pairs, we can't be sure the missing bit isn't in another basic block
7996627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach    // due to a custom inserter playing tricks, so just asserting SPAdj==0
8006627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach    // isn't sufficient. See tMOVCC on Thumb1, for example.
8016627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach    assert((SPAdjCount || SPAdj == 0) &&
8026627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach           "Unbalanced call frame setup / destroy pairs?");
80349dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng  }
80458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner}
805b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby
8069a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach/// scavengeFrameVirtualRegs - Replace all frame index virtual registers
8079a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach/// with physical registers. Use the register scavenger to find an
8089a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach/// appropriate register to use.
80919273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick///
81019273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick/// FIXME: Iterating over the instruction stream is unnecessary. We can simply
81119273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick/// iterate over the vreg use list, which at this point only contains machine
81219273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick/// operands for which eliminateFrameIndex need a new scratch reg.
8133d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbachvoid PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) {
8143d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach  // Run through the instructions and find any virtual registers.
8153d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach  for (MachineFunction::iterator BB = Fn.begin(),
8163d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach       E = Fn.end(); BB != E; ++BB) {
8173d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach    RS->enterBasicBlock(BB);
8183d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach
819700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach    unsigned VirtReg = 0;
820700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach    unsigned ScratchReg = 0;
821e40bf5f9f40a4672cd55bfa51c64a4bb6f4b2f8fJim Grosbach    int SPAdj = 0;
8223d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach
823b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbach    // The instruction stream may change in the loop, so check BB->end()
824b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbach    // directly.
825332553768242e82383df61d9161d1a665bfb3122Jim Grosbach    for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) {
8263d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach      MachineInstr *MI = I;
827332553768242e82383df61d9161d1a665bfb3122Jim Grosbach      for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
8283d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach        if (MI->getOperand(i).isReg()) {
829b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbach          MachineOperand &MO = MI->getOperand(i);
830b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbach          unsigned Reg = MO.getReg();
83132030fe021ee614df6fdd77a2228e0e265049f3dJim Grosbach          if (Reg == 0)
8329a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach            continue;
833700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach          if (!TargetRegisterInfo::isVirtualRegister(Reg))
83432030fe021ee614df6fdd77a2228e0e265049f3dJim Grosbach            continue;
835c52b3cced8aebbc665021ec6b8bcd0974c4ad7aeJim Grosbach
836700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach          ++NumVirtualFrameRegs;
8379a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach
838e40bf5f9f40a4672cd55bfa51c64a4bb6f4b2f8fJim Grosbach          // Have we already allocated a scratch register for this virtual?
839700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach          if (Reg != VirtReg) {
840e40bf5f9f40a4672cd55bfa51c64a4bb6f4b2f8fJim Grosbach            // When we first encounter a new virtual register, it
841e40bf5f9f40a4672cd55bfa51c64a4bb6f4b2f8fJim Grosbach            // must be a definition.
842e40bf5f9f40a4672cd55bfa51c64a4bb6f4b2f8fJim Grosbach            assert(MI->getOperand(i).isDef() &&
843e40bf5f9f40a4672cd55bfa51c64a4bb6f4b2f8fJim Grosbach                   "frame index virtual missing def!");
844332553768242e82383df61d9161d1a665bfb3122Jim Grosbach            // Scavenge a new scratch register
845700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach            VirtReg = Reg;
846332553768242e82383df61d9161d1a665bfb3122Jim Grosbach            const TargetRegisterClass *RC = Fn.getRegInfo().getRegClass(Reg);
847700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach            ScratchReg = RS->scavengeRegister(RC, I, SPAdj);
848c52b3cced8aebbc665021ec6b8bcd0974c4ad7aeJim Grosbach            ++NumScavengedRegs;
8493d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach          }
850c0c7c2b6061e7ca2d528bbedadb1bea0561c9158Jim Grosbach          // Replace this reference to the virtual register with the
851332553768242e82383df61d9161d1a665bfb3122Jim Grosbach          // scratch register.
852700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach          assert (ScratchReg && "Missing scratch register!");
853700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach          MI->getOperand(i).setReg(ScratchReg);
8549a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach
8553d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach        }
856332553768242e82383df61d9161d1a665bfb3122Jim Grosbach      }
8570f657b156f3d0890584bedda7294932a20b2ea16Jim Grosbach      RS->forward(I);
8580f657b156f3d0890584bedda7294932a20b2ea16Jim Grosbach      ++I;
8593d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach    }
8603d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach  }
8613d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach}
862