PrologEpilogInserter.cpp revision 25600cf50df79a6e7f8365a3ca7e940592e8ca74
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"
24c36b7069b42bece963b7e6adf020353ce990ef76Evan Cheng#include "llvm/InlineAsm.h"
25ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby#include "llvm/CodeGen/MachineDominators.h"
26ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby#include "llvm/CodeGen/MachineLoopInfo.h"
2758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner#include "llvm/CodeGen/MachineInstr.h"
28eb24db9727a7babe863d5afe70c7bda3a460da18Chris Lattner#include "llvm/CodeGen/MachineFrameInfo.h"
2984bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner#include "llvm/CodeGen/MachineRegisterInfo.h"
3049dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng#include "llvm/CodeGen/RegisterScavenging.h"
3158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner#include "llvm/Target/TargetMachine.h"
3276927d758657b3a511c73467ec5a7288795c1513Rafael Espindola#include "llvm/Target/TargetOptions.h"
336f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman#include "llvm/Target/TargetRegisterInfo.h"
3416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov#include "llvm/Target/TargetFrameLowering.h"
353501feab811c86c9659248a4875fc31a3165f84dChris Lattner#include "llvm/Target/TargetInstrInfo.h"
363d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach#include "llvm/Support/CommandLine.h"
37a4f0b3a084d120cfc5b5bb06f64b222f5cb72740Chris Lattner#include "llvm/Support/Compiler.h"
383d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/Support/Debug.h"
393d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach#include "llvm/ADT/IndexedMap.h"
40dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling#include "llvm/ADT/SmallSet.h"
41c52b3cced8aebbc665021ec6b8bcd0974c4ad7aeJim Grosbach#include "llvm/ADT/Statistic.h"
428e3347332120956538a6d882b02719e34b57f0cdEvan Cheng#include "llvm/ADT/STLExtras.h"
43c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng#include <climits>
44ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby
4505d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattnerusing namespace llvm;
46d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
47378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosbychar PEI::ID = 0;
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",
55ce665bd2e2b581ab0858d1afe359192bac96b868Owen Anderson                "Prologue/Epilogue Insertion", false, false)
56b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby
57c52b3cced8aebbc665021ec6b8bcd0974c4ad7aeJim GrosbachSTATISTIC(NumVirtualFrameRegs, "Number of virtual frame regs encountered");
58c52b3cced8aebbc665021ec6b8bcd0974c4ad7aeJim GrosbachSTATISTIC(NumScavengedRegs, "Number of frame index regs scavenged");
59b10946a5a938a433ca4d7301b8b5ff5a8c11a7ffEvan ChengSTATISTIC(NumBytesStackSpace,
60b10946a5a938a433ca4d7301b8b5ff5a8c11a7ffEvan Cheng          "Number of bytes used for stack in all functions");
61c52b3cced8aebbc665021ec6b8bcd0974c4ad7aeJim Grosbach
6258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// createPrologEpilogCodeInserter - This function returns a pass that inserts
6358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// prolog and epilog code, and eliminates abstract frame references.
6458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner///
6505d8350c12d8d81de1d8af6f7da155bc1c1da50eChris LattnerFunctionPass *llvm::createPrologEpilogCodeInserter() { return new PEI(); }
6658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
67378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby/// runOnMachineFunction - Insert prolog/epilog code and replace abstract
68378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby/// frame indexes with appropriate references.
69b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby///
70378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosbybool PEI::runOnMachineFunction(MachineFunction &Fn) {
71c5ec8a78ea898087ad361e5b755f74a76150e5fdAnton Korobeynikov  const Function* F = Fn.getFunction();
72b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby  const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo();
7316c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = Fn.getTarget().getFrameLowering();
7494c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov
75378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  RS = TRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : NULL;
7665c58daa8b8985d2116216043103009815a55e77Jim Grosbach  FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(Fn);
77378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby
78b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling  // Calculate the MaxCallFrameSize and AdjustsStack variables for the
79b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling  // function's frame information. Also eliminates call frame pseudo
80b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling  // instructions.
8133b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  calculateCallsInformation(Fn);
8233b350bf24be396a127c81af045468765731afc7Anton Korobeynikov
83378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  // Allow the target machine to make some adjustments to the function
84378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  // e.g. UsedPhysRegs before calculateCalleeSavedRegisters.
8594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov  TFI->processFunctionBeforeCalleeSavedScan(Fn, RS);
86378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby
8733b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  // Scan the function for modified callee saved registers and insert spill code
8833b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  // for any callee saved registers that are modified.
89378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  calculateCalleeSavedRegisters(Fn);
90378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby
91378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  // Determine placement of CSR spill/restore code:
925b02901e91a155feca84d7383c1e569aacd1739eJim Grosbach  //  - With shrink wrapping, place spills and restores to tightly
93378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  //    enclose regions in the Machine CFG of the function where
945b02901e91a155feca84d7383c1e569aacd1739eJim Grosbach  //    they are used.
955b02901e91a155feca84d7383c1e569aacd1739eJim Grosbach  //  - Without shink wrapping (default), place all spills in the
96378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  //    entry block, all restores in return blocks.
97378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  placeCSRSpillsAndRestores(Fn);
98378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby
99378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  // Add the code to save and restore the callee saved registers
100c5ec8a78ea898087ad361e5b755f74a76150e5fdAnton Korobeynikov  if (!F->hasFnAttr(Attribute::Naked))
101c5ec8a78ea898087ad361e5b755f74a76150e5fdAnton Korobeynikov    insertCSRSpillsAndRestores(Fn);
102378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby
103378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  // Allow the target machine to make final modifications to the function
104378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  // before the frame layout is finalized.
10594c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov  TFI->processFunctionBeforeFrameFinalized(Fn);
106378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby
107378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  // Calculate actual frame offsets for all abstract stack objects...
108378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  calculateFrameObjectOffsets(Fn);
109378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby
110378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  // Add prolog and epilog code to the function.  This function is required
111378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  // to align the stack frame as necessary for any stack variables or
112b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling  // called functions.  Because of this, calculateCalleeSavedRegisters()
113b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling  // must be called before this function in order to set the AdjustsStack
114378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  // and MaxCallFrameSize variables.
115c5ec8a78ea898087ad361e5b755f74a76150e5fdAnton Korobeynikov  if (!F->hasFnAttr(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
129378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  delete RS;
130378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  clearAllSets();
131b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby  return true;
132ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby}
133ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby
134378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby#if 0
135378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosbyvoid PEI::getAnalysisUsage(AnalysisUsage &AU) const {
136845012e6d31799c7fbd1193fa1af8ee2d12e9231Dan Gohman  AU.setPreservesCFG();
137378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  if (ShrinkWrapping || ShrinkWrapFunc != "") {
138378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby    AU.addRequired<MachineLoopInfo>();
139378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby    AU.addRequired<MachineDominatorTree>();
140b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby  }
141378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  AU.addPreserved<MachineLoopInfo>();
142378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  AU.addPreserved<MachineDominatorTree>();
143378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby  MachineFunctionPass::getAnalysisUsage(AU);
144ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby}
145378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby#endif
146ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby
147b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling/// calculateCallsInformation - Calculate the MaxCallFrameSize and AdjustsStack
14833b350bf24be396a127c81af045468765731afc7Anton Korobeynikov/// variables for the function's frame information and eliminate call frame
14933b350bf24be396a127c81af045468765731afc7Anton Korobeynikov/// pseudo instructions.
15033b350bf24be396a127c81af045468765731afc7Anton Korobeynikovvoid PEI::calculateCallsInformation(MachineFunction &Fn) {
1516f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman  const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo();
152d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng  const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo();
15316c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = Fn.getTarget().getFrameLowering();
1549e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman  MachineFrameInfo *MFI = Fn.getFrameInfo();
15558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
15633b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  unsigned MaxCallFrameSize = 0;
157b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling  bool AdjustsStack = MFI->adjustsStack();
15858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
15958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  // Get the function call frame set-up and tear-down instruction opcode
160d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng  int FrameSetupOpcode   = TII.getCallFrameSetupOpcode();
161d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng  int FrameDestroyOpcode = TII.getCallFrameDestroyOpcode();
16258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
16333b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  // Early exit for targets which have no call frame setup/destroy pseudo
16433b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  // instructions.
16533b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  if (FrameSetupOpcode == -1 && FrameDestroyOpcode == -1)
16658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner    return;
16758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
1685c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng  std::vector<MachineBasicBlock::iterator> FrameSDOps;
16958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB)
1705c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng    for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I)
171c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos      if (I->getOpcode() == FrameSetupOpcode ||
172d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner          I->getOpcode() == FrameDestroyOpcode) {
1732a82ef317c39ac436f80854c7ddbb06bfddeada1Chris Lattner        assert(I->getNumOperands() >= 1 && "Call Frame Setup/Destroy Pseudo"
174d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner               " instructions should have a single immediate argument!");
1759e3304900ff69c4920fea7369c9c36916c4a6a6aChris Lattner        unsigned Size = I->getOperand(0).getImm();
176d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner        if (Size > MaxCallFrameSize) MaxCallFrameSize = Size;
177b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling        AdjustsStack = true;
1785c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng        FrameSDOps.push_back(I);
179518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner      } else if (I->isInlineAsm()) {
180f1e309eb4862459a76445942ba4dafc433b6f317Dale Johannesen        // Some inline asm's need a stack frame, as indicated by operand 1.
181c36b7069b42bece963b7e6adf020353ce990ef76Evan Cheng        unsigned ExtraInfo = I->getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
182c36b7069b42bece963b7e6adf020353ce990ef76Evan Cheng        if (ExtraInfo & InlineAsm::Extra_IsAlignStack)
183f1e309eb4862459a76445942ba4dafc433b6f317Dale Johannesen          AdjustsStack = true;
18458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner      }
18558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
186b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling  MFI->setAdjustsStack(AdjustsStack);
1879e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman  MFI->setMaxCallFrameSize(MaxCallFrameSize);
1888e3347332120956538a6d882b02719e34b57f0cdEvan Cheng
189058a024eb7265239d527680b0a448cdb48102a46Bill Wendling  for (std::vector<MachineBasicBlock::iterator>::iterator
190058a024eb7265239d527680b0a448cdb48102a46Bill Wendling         i = FrameSDOps.begin(), e = FrameSDOps.end(); i != e; ++i) {
191058a024eb7265239d527680b0a448cdb48102a46Bill Wendling    MachineBasicBlock::iterator I = *i;
192058a024eb7265239d527680b0a448cdb48102a46Bill Wendling
193058a024eb7265239d527680b0a448cdb48102a46Bill Wendling    // If call frames are not being included as part of the stack frame, and
1944642ad3af1cf508ac320b9afd25b065f08b36574Jim Grosbach    // the target doesn't indicate otherwise, remove the call frame pseudos
1954642ad3af1cf508ac320b9afd25b065f08b36574Jim Grosbach    // here. The sub/add sp instruction pairs are still inserted, but we don't
1964642ad3af1cf508ac320b9afd25b065f08b36574Jim Grosbach    // need to track the SP adjustment for frame index elimination.
197d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov    if (TFI->canSimplifyCallFramePseudos(Fn))
1988e3347332120956538a6d882b02719e34b57f0cdEvan Cheng      RegInfo->eliminateCallFramePseudoInstr(Fn, *I->getParent(), I);
1995c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng  }
20033b350bf24be396a127c81af045468765731afc7Anton Korobeynikov}
20133b350bf24be396a127c81af045468765731afc7Anton Korobeynikov
20233b350bf24be396a127c81af045468765731afc7Anton Korobeynikov
20333b350bf24be396a127c81af045468765731afc7Anton Korobeynikov/// calculateCalleeSavedRegisters - Scan the function for modified callee saved
20433b350bf24be396a127c81af045468765731afc7Anton Korobeynikov/// registers.
20533b350bf24be396a127c81af045468765731afc7Anton Korobeynikovvoid PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) {
20633b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo();
20716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = Fn.getTarget().getFrameLowering();
2089e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman  MachineFrameInfo *MFI = Fn.getFrameInfo();
20933b350bf24be396a127c81af045468765731afc7Anton Korobeynikov
21033b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  // Get the callee saved register list...
21133b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  const unsigned *CSRegs = RegInfo->getCalleeSavedRegs(&Fn);
21233b350bf24be396a127c81af045468765731afc7Anton Korobeynikov
21333b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  // These are used to keep track the callee-save area. Initialize them.
21433b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  MinCSFrameIndex = INT_MAX;
21533b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  MaxCSFrameIndex = 0;
21633b350bf24be396a127c81af045468765731afc7Anton Korobeynikov
21733b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  // Early exit for targets which have no callee saved registers.
21833b350bf24be396a127c81af045468765731afc7Anton Korobeynikov  if (CSRegs == 0 || CSRegs[0] == 0)
21933b350bf24be396a127c81af045468765731afc7Anton Korobeynikov    return;
22058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
2218c5358c93675b009ba2d57c3a5980f6bc58ba536Dale Johannesen  // In Naked functions we aren't going to save any registers.
2228c5358c93675b009ba2d57c3a5980f6bc58ba536Dale Johannesen  if (Fn.getFunction()->hasFnAttr(Attribute::Naked))
2238c5358c93675b009ba2d57c3a5980f6bc58ba536Dale Johannesen    return;
2248c5358c93675b009ba2d57c3a5980f6bc58ba536Dale Johannesen
22508ede262a744f99429658fadb43662441bdcb42dJim Laskey  std::vector<CalleeSavedInfo> CSI;
22658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  for (unsigned i = 0; CSRegs[i]; ++i) {
22758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner    unsigned Reg = CSRegs[i];
228a2a98fd0ddd2ae277be7cdd62aae92f6c5155e07Jakob Stoklund Olesen    if (Fn.getRegInfo().isPhysRegOrOverlapUsed(Reg)) {
229058a024eb7265239d527680b0a448cdb48102a46Bill Wendling      // If the reg is modified, save it!
23042d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola      CSI.push_back(CalleeSavedInfo(Reg));
23173ff5120eb8b8c0ccbfed8a17f1024c67a75f319Alkis Evlogimenos    }
23258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  }
23358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
234f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey  if (CSI.empty())
235c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng    return;   // Early exit if no callee saved registers are modified!
23658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
237c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner  unsigned NumFixedSpillSlots;
23816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering::SpillSlot *FixedSpillSlots =
239ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng    TFI->getCalleeSavedSpillSlots(NumFixedSpillSlots);
240c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner
24158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  // Now that we know which registers need to be saved and restored, allocate
24258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  // stack slots for them.
243058a024eb7265239d527680b0a448cdb48102a46Bill Wendling  for (std::vector<CalleeSavedInfo>::iterator
244058a024eb7265239d527680b0a448cdb48102a46Bill Wendling         I = CSI.begin(), E = CSI.end(); I != E; ++I) {
245058a024eb7265239d527680b0a448cdb48102a46Bill Wendling    unsigned Reg = I->getReg();
24642d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola    const TargetRegisterClass *RC = RegInfo->getMinimalPhysRegClass(Reg);
247c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner
248910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng    int FrameIdx;
249910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng    if (RegInfo->hasReservedSpillSlot(Fn, Reg, FrameIdx)) {
250910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng      I->setFrameIdx(FrameIdx);
251910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng      continue;
252910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng    }
253910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng
254c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner    // Check to see if this physreg must be spilled to a particular stack slot
255c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner    // on this target.
25616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov    const TargetFrameLowering::SpillSlot *FixedSlot = FixedSpillSlots;
257c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner    while (FixedSlot != FixedSpillSlots+NumFixedSpillSlots &&
2588ff95de83cbe85d939535d2f4fb5f9b2b721081aTilmann Scheller           FixedSlot->Reg != Reg)
259c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner      ++FixedSlot;
260c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner
261058a024eb7265239d527680b0a448cdb48102a46Bill Wendling    if (FixedSlot == FixedSpillSlots + NumFixedSpillSlots) {
262c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner      // Nope, just spill it anywhere convenient.
2635feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng      unsigned Align = RC->getAlignment();
2645feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng      unsigned StackAlign = TFI->getStackAlignment();
265058a024eb7265239d527680b0a448cdb48102a46Bill Wendling
266058a024eb7265239d527680b0a448cdb48102a46Bill Wendling      // We may not be able to satisfy the desired alignment specification of
267058a024eb7265239d527680b0a448cdb48102a46Bill Wendling      // the TargetRegisterClass if the stack alignment is smaller. Use the
268058a024eb7265239d527680b0a448cdb48102a46Bill Wendling      // min.
2695feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng      Align = std::min(Align, StackAlign);
2709e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman      FrameIdx = MFI->CreateStackObject(RC->getSize(), Align, true);
271c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng      if ((unsigned)FrameIdx < MinCSFrameIndex) MinCSFrameIndex = FrameIdx;
272c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng      if ((unsigned)FrameIdx > MaxCSFrameIndex) MaxCSFrameIndex = FrameIdx;
273c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner    } else {
274c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner      // Spill it to the stack where we must.
275ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng      FrameIdx = MFI->CreateFixedObject(RC->getSize(), FixedSlot->Offset, true);
276c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner    }
277058a024eb7265239d527680b0a448cdb48102a46Bill Wendling
278058a024eb7265239d527680b0a448cdb48102a46Bill Wendling    I->setFrameIdx(FrameIdx);
27958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  }
28008ede262a744f99429658fadb43662441bdcb42dJim Laskey
2819e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman  MFI->setCalleeSavedInfo(CSI);
282c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner}
283c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner
284ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby/// insertCSRSpillsAndRestores - Insert spill and restore code for
285ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby/// callee saved registers used in the function, handling shrink wrapping.
286c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner///
287ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosbyvoid PEI::insertCSRSpillsAndRestores(MachineFunction &Fn) {
288f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey  // Get callee saved register information.
2899e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman  MachineFrameInfo *MFI = Fn.getFrameInfo();
2909e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman  const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
291ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby
2929e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman  MFI->setCalleeSavedInfoValid(true);
293d62c9a697b53f9e754926a89126fd121220ed09bJakob Stoklund Olesen
294c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng  // Early exit if no callee saved registers are modified!
295f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey  if (CSI.empty())
296edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman    return;
297c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner
298f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson  const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo();
29916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = Fn.getTarget().getFrameLowering();
300746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng  const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo();
301ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby  MachineBasicBlock::iterator I;
30200dff8dda29b5a249cd99405ce26e84cef13ba53Evan Cheng
303b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby  if (! ShrinkWrapThisFunction) {
304b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    // Spill using target interface.
305b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    I = EntryBlock->begin();
306cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov    if (!TFI->spillCalleeSavedRegisters(*EntryBlock, I, CSI, TRI)) {
307b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
308ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby        // Add the callee-saved register as live-in.
309ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby        // It's killed at the spill.
310b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby        EntryBlock->addLiveIn(CSI[i].getReg());
311ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby
312ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby        // Insert the spill to the stack frame.
31342d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola        unsigned Reg = CSI[i].getReg();
31442d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola        const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
31542d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola        TII.storeRegToStackSlot(*EntryBlock, I, Reg, true,
31642d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola                                CSI[i].getFrameIdx(), RC, TRI);
317ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby      }
318ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng    }
319ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby
320b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    // Restore using target interface.
321b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    for (unsigned ri = 0, re = ReturnBlocks.size(); ri != re; ++ri) {
322b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      MachineBasicBlock* MBB = ReturnBlocks[ri];
323c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos      I = MBB->end(); --I;
32458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
325f7c094000f4baf094b1d60ba68a5b4e0193c502aBill Wendling      // Skip over all terminator instructions, which are part of the return
3264fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner      // sequence.
3274fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner      MachineBasicBlock::iterator I2 = I;
3285a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng      while (I2 != MBB->begin() && (--I2)->isTerminator())
3294fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner        I = I2;
3304fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner
331dfd58709cc78e841ef4a50ba75d940473031617eChris Lattner      bool AtStart = I == MBB->begin();
332ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner      MachineBasicBlock::iterator BeforeI = I;
333ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner      if (!AtStart)
334ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner        --BeforeI;
335ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby
336ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby      // Restore all registers immediately before the return and any
3377a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner      // terminators that precede it.
338cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov      if (!TFI->restoreCalleeSavedRegisters(*MBB, I, CSI, TRI)) {
339ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng        for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
34042d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola          unsigned Reg = CSI[i].getReg();
34142d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola          const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
34242d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola          TII.loadRegFromStackSlot(*MBB, I, Reg,
343ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby                                   CSI[i].getFrameIdx(),
34442d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola                                   RC, TRI);
345ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng          assert(I != MBB->begin() &&
346ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng                 "loadRegFromStackSlot didn't insert any code!");
347ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby          // Insert in reverse order.  loadRegFromStackSlot can insert
348ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby          // multiple instructions.
349ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng          if (AtStart)
350ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng            I = MBB->begin();
351ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng          else {
352ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng            I = BeforeI;
353ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng            ++I;
354ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng          }
355ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner        }
35658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner      }
357b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    }
358b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    return;
359b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby  }
360ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby
361b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby  // Insert spills.
362b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby  std::vector<CalleeSavedInfo> blockCSI;
363b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby  for (CSRegBlockMap::iterator BI = CSRSave.begin(),
364b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby         BE = CSRSave.end(); BI != BE; ++BI) {
365b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    MachineBasicBlock* MBB = BI->first;
366b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    CSRegSet save = BI->second;
367ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby
368b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    if (save.empty())
369b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      continue;
370ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby
371b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    blockCSI.clear();
372b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    for (CSRegSet::iterator RI = save.begin(),
373b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby           RE = save.end(); RI != RE; ++RI) {
374b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      blockCSI.push_back(CSI[*RI]);
375b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    }
376b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    assert(blockCSI.size() > 0 &&
377b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby           "Could not collect callee saved register info");
378b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby
379b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    I = MBB->begin();
380b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby
381b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    // When shrink wrapping, use stack slot stores/loads.
382b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    for (unsigned i = 0, e = blockCSI.size(); i != e; ++i) {
383b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      // Add the callee-saved register as live-in.
384b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      // It's killed at the spill.
385b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      MBB->addLiveIn(blockCSI[i].getReg());
386b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby
387b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      // Insert the spill to the stack frame.
38842d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola      unsigned Reg = blockCSI[i].getReg();
38942d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola      const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
39042d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola      TII.storeRegToStackSlot(*MBB, I, Reg,
391b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby                              true,
392b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby                              blockCSI[i].getFrameIdx(),
39342d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola                              RC, TRI);
394b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    }
395b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby  }
396b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby
397b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby  for (CSRegBlockMap::iterator BI = CSRRestore.begin(),
398b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby         BE = CSRRestore.end(); BI != BE; ++BI) {
399b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    MachineBasicBlock* MBB = BI->first;
400b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    CSRegSet restore = BI->second;
401b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby
402b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    if (restore.empty())
403b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      continue;
404b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby
405b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    blockCSI.clear();
406b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    for (CSRegSet::iterator RI = restore.begin(),
407b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby           RE = restore.end(); RI != RE; ++RI) {
408b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      blockCSI.push_back(CSI[*RI]);
409b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    }
410b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    assert(blockCSI.size() > 0 &&
411b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby           "Could not find callee saved register info");
412b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby
413b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    // If MBB is empty and needs restores, insert at the _beginning_.
414b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    if (MBB->empty()) {
415b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      I = MBB->begin();
416b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    } else {
417b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      I = MBB->end();
418b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      --I;
419b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby
420b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      // Skip over all terminator instructions, which are part of the
421b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      // return sequence.
4225a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng      if (! I->isTerminator()) {
423b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby        ++I;
424ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby      } else {
425b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby        MachineBasicBlock::iterator I2 = I;
4265a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng        while (I2 != MBB->begin() && (--I2)->isTerminator())
427b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby          I = I2;
428ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby      }
429b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    }
430ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby
431b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    bool AtStart = I == MBB->begin();
432b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    MachineBasicBlock::iterator BeforeI = I;
433b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    if (!AtStart)
434b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      --BeforeI;
435b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby
436b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    // Restore all registers immediately before the return and any
4377a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner    // terminators that precede it.
438b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby    for (unsigned i = 0, e = blockCSI.size(); i != e; ++i) {
43942d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola      unsigned Reg = blockCSI[i].getReg();
44042d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola      const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
44142d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola      TII.loadRegFromStackSlot(*MBB, I, Reg,
442b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby                               blockCSI[i].getFrameIdx(),
44342d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola                               RC, TRI);
444b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      assert(I != MBB->begin() &&
445b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby             "loadRegFromStackSlot didn't insert any code!");
446b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      // Insert in reverse order.  loadRegFromStackSlot can insert
447b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      // multiple instructions.
448b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      if (AtStart)
449b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby        I = MBB->begin();
450b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby      else {
451b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby        I = BeforeI;
452b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby        ++I;
453ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby      }
45458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner    }
455ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby  }
45658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner}
45758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
458cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling/// AdjustStackOffset - Helper function used to adjust the stack frame offset.
459cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendlingstatic inline void
4609e9aa44d1a33fb845268ba07b726a31f26195690Dan GohmanAdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx,
461cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling                  bool StackGrowsDown, int64_t &Offset,
462cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling                  unsigned &MaxAlign) {
46394188d4e67cf1c570ad87dbabf198931033d628eBob Wilson  // If the stack grows down, add the object size to find the lowest address.
464cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling  if (StackGrowsDown)
4659e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman    Offset += MFI->getObjectSize(FrameIdx);
466cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling
4679e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman  unsigned Align = MFI->getObjectAlignment(FrameIdx);
468cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling
469cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling  // If the alignment of this object is greater than that of the stack, then
470cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling  // increase the stack alignment to match.
471cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling  MaxAlign = std::max(MaxAlign, Align);
472cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling
473cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling  // Adjust to alignment boundary.
474cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling  Offset = (Offset + Align - 1) / Align * Align;
475cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling
476cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling  if (StackGrowsDown) {
4773d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach    DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << -Offset << "]\n");
4789e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman    MFI->setObjectOffset(FrameIdx, -Offset); // Set the computed offset
479cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling  } else {
4803d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach    DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << Offset << "]\n");
4819e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman    MFI->setObjectOffset(FrameIdx, Offset);
4829e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman    Offset += MFI->getObjectSize(FrameIdx);
483cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling  }
484cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling}
48558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
48658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the
48792b9fcea7b3180ed18f379212d14bd5cea7a1954Chris Lattner/// abstract stack objects.
48858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner///
48958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattnervoid PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
49016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering &TFI = *Fn.getTarget().getFrameLowering();
491edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman
49258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  bool StackGrowsDown =
49316c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov    TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown;
494edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman
49558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  // Loop over all of the stack objects, assigning sequential addresses...
4969e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman  MachineFrameInfo *MFI = Fn.getFrameInfo();
49758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
49805d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner  // Start at the beginning of the local area.
499577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner  // The Offset is the distance from the stack top in the direction
500c0d6012b31afa2220306afa27db1b02e18427776Dan Gohman  // of stack growth -- so it's always nonnegative.
501c34666ee1871d47dfa4865c7138902dd1b770101Bob Wilson  int LocalAreaOffset = TFI.getOffsetOfLocalArea();
502577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner  if (StackGrowsDown)
503c34666ee1871d47dfa4865c7138902dd1b770101Bob Wilson    LocalAreaOffset = -LocalAreaOffset;
504c34666ee1871d47dfa4865c7138902dd1b770101Bob Wilson  assert(LocalAreaOffset >= 0
505577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner         && "Local area offset should be in direction of stack growth");
506c34666ee1871d47dfa4865c7138902dd1b770101Bob Wilson  int64_t Offset = LocalAreaOffset;
507577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner
508577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner  // If there are fixed sized objects that are preallocated in the local area,
509577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner  // non-fixed objects can't be allocated right at the start of local area.
510ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby  // We currently don't support filling in holes in between fixed sized
511ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby  // objects, so we adjust 'Offset' to point to the end of last fixed sized
51205d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner  // preallocated object.
5139e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman  for (int i = MFI->getObjectIndexBegin(); i != 0; ++i) {
514a401b1e1c5eb9563617db8a2477b4c5f8b239521Chris Lattner    int64_t FixedOff;
515577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner    if (StackGrowsDown) {
516577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner      // The maximum distance from the stack pointer is at lower address of
517577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner      // the object -- which is given by offset. For down growing stack
518577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner      // the offset is negative, so we negate the offset to get the distance.
5199e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman      FixedOff = -MFI->getObjectOffset(i);
520577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner    } else {
521edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman      // The maximum distance from the start pointer is at the upper
522577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner      // address of the object.
5239e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman      FixedOff = MFI->getObjectOffset(i) + MFI->getObjectSize(i);
524edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman    }
525edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman    if (FixedOff > Offset) Offset = FixedOff;
52605d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner  }
52705d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner
528c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng  // First assign frame offsets to stack objects that are used to spill
529ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng  // callee saved registers.
530c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng  if (StackGrowsDown) {
5315c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng    for (unsigned i = MinCSFrameIndex; i <= MaxCSFrameIndex; ++i) {
532b4c14aaa50b58ac723d0ed179695e1cd7296572aEric Christopher      // If the stack grows down, we need to add the size to find the lowest
533c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng      // address of the object.
5349e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman      Offset += MFI->getObjectSize(i);
535c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng
5369e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman      unsigned Align = MFI->getObjectAlignment(i);
537c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng      // Adjust to alignment boundary
538c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng      Offset = (Offset+Align-1)/Align*Align;
539c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng
5409e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman      MFI->setObjectOffset(i, -Offset);        // Set the computed offset
541c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng    }
542c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng  } else {
543a8c63f0fc9feb48f17d702a907f065959c41e337Bruno Cardoso Lopes    int MaxCSFI = MaxCSFrameIndex, MinCSFI = MinCSFrameIndex;
544a8c63f0fc9feb48f17d702a907f065959c41e337Bruno Cardoso Lopes    for (int i = MaxCSFI; i >= MinCSFI ; --i) {
5459e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman      unsigned Align = MFI->getObjectAlignment(i);
546c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng      // Adjust to alignment boundary
547c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng      Offset = (Offset+Align-1)/Align*Align;
548c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng
5499e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman      MFI->setObjectOffset(i, Offset);
5509e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman      Offset += MFI->getObjectSize(i);
551c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng    }
552c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng  }
553c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng
5549e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman  unsigned MaxAlign = MFI->getMaxAlignment();
5557545f49a5edfe19612d03e683d8b955c03018056Evan Cheng
55687f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng  // Make sure the special register scavenging spill slot is closest to the
55787f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng  // frame pointer if a frame pointer is required.
5586f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman  const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo();
5590f657b156f3d0890584bedda7294932a20b2ea16Jim Grosbach  if (RS && TFI.hasFP(Fn) && RegInfo->useFPForScavengingIndex(Fn) &&
5600f657b156f3d0890584bedda7294932a20b2ea16Jim Grosbach      !RegInfo->needsStackRealignment(Fn)) {
56187f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng    int SFI = RS->getScavengingFrameIndex();
562cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling    if (SFI >= 0)
5639e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman      AdjustStackOffset(MFI, SFI, StackGrowsDown, Offset, MaxAlign);
56487f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng  }
56587f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng
5664861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach  // FIXME: Once this is working, then enable flag will change to a target
5674861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach  // check for whether the frame is large enough to want to use virtual
5684861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach  // frame index registers. Functions which don't want/need this optimization
5694861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach  // will continue to use the existing code path.
570a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach  if (MFI->getUseLocalStackAllocationBlock()) {
5714861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach    unsigned Align = MFI->getLocalFrameMaxAlign();
5724861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach
5734861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach    // Adjust to alignment boundary.
5744861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach    Offset = (Offset + Align - 1) / Align * Align;
5754861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach
576fecdea0bf77599038eb368db3bc6a38a14900308Jim Grosbach    DEBUG(dbgs() << "Local frame base offset: " << Offset << "\n");
577fecdea0bf77599038eb368db3bc6a38a14900308Jim Grosbach
5783d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach    // Resolve offsets for objects in the local block.
5793d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach    for (unsigned i = 0, e = MFI->getLocalFrameObjectCount(); i != e; ++i) {
5803d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach      std::pair<int, int64_t> Entry = MFI->getLocalFrameObjectMap(i);
58167ff81a08319f916571cea90ed92e17015c8584fJim Grosbach      int64_t FIOffset = (StackGrowsDown ? -Offset : Offset) + Entry.second;
58267ff81a08319f916571cea90ed92e17015c8584fJim Grosbach      DEBUG(dbgs() << "alloc FI(" << Entry.first << ") at SP[" <<
58367ff81a08319f916571cea90ed92e17015c8584fJim Grosbach            FIOffset << "]\n");
58467ff81a08319f916571cea90ed92e17015c8584fJim Grosbach      MFI->setObjectOffset(Entry.first, FIOffset);
5853d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach    }
58667ff81a08319f916571cea90ed92e17015c8584fJim Grosbach    // Allocate the local block
58767ff81a08319f916571cea90ed92e17015c8584fJim Grosbach    Offset += MFI->getLocalFrameSize();
58867ff81a08319f916571cea90ed92e17015c8584fJim Grosbach
58967ff81a08319f916571cea90ed92e17015c8584fJim Grosbach    MaxAlign = std::max(Align, MaxAlign);
5903d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach  }
5913d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach
592b2a4298ce41e7ef80cd75a3c1dfa6433f0759a1aBill Wendling  // Make sure that the stack protector comes before the local variables on the
593b2a4298ce41e7ef80cd75a3c1dfa6433f0759a1aBill Wendling  // stack.
594dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling  SmallSet<int, 16> LargeStackObjs;
595dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling  if (MFI->getStackProtectorIndex() >= 0) {
5969e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman    AdjustStackOffset(MFI, MFI->getStackProtectorIndex(), StackGrowsDown,
597cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling                      Offset, MaxAlign);
598b2a4298ce41e7ef80cd75a3c1dfa6433f0759a1aBill Wendling
599dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling    // Assign large stack objects first.
600dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling    for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) {
601a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach      if (MFI->isObjectPreAllocated(i) &&
602a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach          MFI->getUseLocalStackAllocationBlock())
6033d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach        continue;
604dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling      if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex)
605dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling        continue;
606dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling      if (RS && (int)i == RS->getScavengingFrameIndex())
607dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling        continue;
608dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling      if (MFI->isDeadObjectIndex(i))
609dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling        continue;
610dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling      if (MFI->getStackProtectorIndex() == (int)i)
611dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling        continue;
612dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling      if (!MFI->MayNeedStackProtector(i))
613dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling        continue;
614dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling
615dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling      AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign);
616dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling      LargeStackObjs.insert(i);
617dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling    }
618dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling  }
619dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling
620c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng  // Then assign frame offsets to stack objects that are not used to spill
621ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng  // callee saved registers.
6229e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman  for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) {
623a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach    if (MFI->isObjectPreAllocated(i) &&
624a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach        MFI->getUseLocalStackAllocationBlock())
6253d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach      continue;
626c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng    if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex)
627c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng      continue;
62887f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng    if (RS && (int)i == RS->getScavengingFrameIndex())
62987f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng      continue;
6309e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman    if (MFI->isDeadObjectIndex(i))
631d36531249a9a9500e516148e7e72d4c0a7a4d0eeEvan Cheng      continue;
6329e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman    if (MFI->getStackProtectorIndex() == (int)i)
63344cf38c01ff610139d2e8dbbdc4e6123a3debcddBill Wendling      continue;
634dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling    if (LargeStackObjs.count(i))
635dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling      continue;
636c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng
6379e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman    AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign);
63858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  }
63958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
64087f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng  // Make sure the special register scavenging spill slot is closest to the
64187f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng  // stack pointer.
6420f657b156f3d0890584bedda7294932a20b2ea16Jim Grosbach  if (RS && (!TFI.hasFP(Fn) || RegInfo->needsStackRealignment(Fn) ||
6430f657b156f3d0890584bedda7294932a20b2ea16Jim Grosbach             !RegInfo->useFPForScavengingIndex(Fn))) {
64487f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng    int SFI = RS->getScavengingFrameIndex();
645cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling    if (SFI >= 0)
6469e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman      AdjustStackOffset(MFI, SFI, StackGrowsDown, Offset, MaxAlign);
64787f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng  }
64887f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng
64933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  if (!TFI.targetHandlesStackFrameRounding()) {
6505c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng    // If we have reserved argument space for call sites in the function
6515c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng    // immediately on entry to the current function, count it as part of the
6525c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng    // overall stack size.
653d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov    if (MFI->adjustsStack() && TFI.hasReservedCallFrame(Fn))
6549e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman      Offset += MFI->getMaxCallFrameSize();
655367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng
6560035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson    // Round up the size to a multiple of the alignment.  If the function has
6570035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson    // any calls or alloca's, align to the target's StackAlignment value to
6580035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson    // ensure that the callee's frame or the alloca data is suitably aligned;
6590035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson    // otherwise, for leaf functions, align to the TransientStackAlignment
6600035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson    // value.
6610035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson    unsigned StackAlign;
662b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling    if (MFI->adjustsStack() || MFI->hasVarSizedObjects() ||
6639e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman        (RegInfo->needsStackRealignment(Fn) && MFI->getObjectIndexEnd() != 0))
6640035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson      StackAlign = TFI.getStackAlignment();
6650035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson    else
6660035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson      StackAlign = TFI.getTransientStackAlignment();
667b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling
668b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling    // If the frame pointer is eliminated, all frame offsets will be relative to
669b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling    // SP not FP. Align to MaxAlign so this works.
6700035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson    StackAlign = std::max(StackAlign, MaxAlign);
6710035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson    unsigned AlignMask = StackAlign - 1;
672ea84c5ee952c62dd0c703c9852d7a60715e4a435Chris Lattner    Offset = (Offset + AlignMask) & ~uint64_t(AlignMask);
673367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng  }
674367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng
675367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng  // Update frame info to pretend that this is part of the stack...
676c219d191aadb4f9532bcaea5c5e66f66912656caJakob Stoklund Olesen  int64_t StackSize = Offset - LocalAreaOffset;
677c219d191aadb4f9532bcaea5c5e66f66912656caJakob Stoklund Olesen  MFI->setStackSize(StackSize);
678c219d191aadb4f9532bcaea5c5e66f66912656caJakob Stoklund Olesen  NumBytesStackSpace += StackSize;
6794ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner}
6804ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner
681c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng/// insertPrologEpilogCode - Scan the function for modified callee saved
682c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng/// registers, insert spill code for these callee saved registers, then add
6834ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner/// prolog and epilog code to the function.
6844ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner///
6854ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattnervoid PEI::insertPrologEpilogCode(MachineFunction &Fn) {
68616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering &TFI = *Fn.getTarget().getFrameLowering();
687874384e20f618d6ac932628db64e048757213fcdAnton Korobeynikov
6884ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner  // Add prologue to the function...
68933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  TFI.emitPrologue(Fn);
6904ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner
6914ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner  // Add epilogue to restore the callee-save registers in each exiting block
6924ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner  for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) {
6934ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner    // If last instruction is a return instruction, add an epilogue
6945a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng    if (!I->empty() && I->back().isReturn())
69533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov      TFI.emitEpilogue(Fn, *I);
6964ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner  }
69776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola
698e81abfd30b7c81735e9f3d79006c2653690aa592Rafael Espindola  // Emit additional code that is required to support segmented stacks, if
699e81abfd30b7c81735e9f3d79006c2653690aa592Rafael Espindola  // we've been asked for it.  This, when linked with a runtime with support
700e81abfd30b7c81735e9f3d79006c2653690aa592Rafael Espindola  // for segmented stacks (libgcc is one), will result in allocating stack
701e81abfd30b7c81735e9f3d79006c2653690aa592Rafael Espindola  // space in small chunks instead of one large contiguous block.
7028a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky  if (Fn.getTarget().Options.EnableSegmentedStacks)
70376927d758657b3a511c73467ec5a7288795c1513Rafael Espindola    TFI.adjustForSegmentedStacks(Fn);
70458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner}
70558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
70658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// replaceFrameIndices - Replace all MO_FrameIndex operands with physical
70758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// register references and actual offsets.
70858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner///
70958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattnervoid PEI::replaceFrameIndices(MachineFunction &Fn) {
71058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  if (!Fn.getFrameInfo()->hasStackObjects()) return; // Nothing to do?
71158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
71258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  const TargetMachine &TM = Fn.getTarget();
71358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner  assert(TM.getRegisterInfo() && "TM::getRegisterInfo() must be implemented!");
714d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng  const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo();
7156f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman  const TargetRegisterInfo &TRI = *TM.getRegisterInfo();
71616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = TM.getFrameLowering();
7178e3347332120956538a6d882b02719e34b57f0cdEvan Cheng  bool StackGrowsDown =
71816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov    TFI->getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown;
719d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng  int FrameSetupOpcode   = TII.getCallFrameSetupOpcode();
720d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng  int FrameDestroyOpcode = TII.getCallFrameDestroyOpcode();
72158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner
722ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby  for (MachineFunction::iterator BB = Fn.begin(),
723ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby         E = Fn.end(); BB != E; ++BB) {
7246627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach#ifndef NDEBUG
7256627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach    int SPAdjCount = 0; // frame setup / destroy count.
7266627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach#endif
7278e3347332120956538a6d882b02719e34b57f0cdEvan Cheng    int SPAdj = 0;  // SP offset due to call frame setup / destroy.
7283d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach    if (RS && !FrameIndexVirtualScavenging) RS->enterBasicBlock(BB);
729ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby
7300ebe9c132c6b9c74b334f0c7503e702b499575d5Chris Lattner    for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) {
731405abffd5eb1ad1841491e51943b598c935f309bBill Wendling
732405abffd5eb1ad1841491e51943b598c935f309bBill Wendling      if (I->getOpcode() == FrameSetupOpcode ||
733405abffd5eb1ad1841491e51943b598c935f309bBill Wendling          I->getOpcode() == FrameDestroyOpcode) {
7346627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach#ifndef NDEBUG
7356627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach        // Track whether we see even pairs of them
7366627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach        SPAdjCount += I->getOpcode() == FrameSetupOpcode ? 1 : -1;
7376627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach#endif
738405abffd5eb1ad1841491e51943b598c935f309bBill Wendling        // Remember how much SP has been adjusted to create the call
739405abffd5eb1ad1841491e51943b598c935f309bBill Wendling        // frame.
74071a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner        int Size = I->getOperand(0).getImm();
741405abffd5eb1ad1841491e51943b598c935f309bBill Wendling
74271a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner        if ((!StackGrowsDown && I->getOpcode() == FrameSetupOpcode) ||
74371a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner            (StackGrowsDown && I->getOpcode() == FrameDestroyOpcode))
74471a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner          Size = -Size;
745988a5782d3ce3cddc65d57d6aac7312d33ed59abBill Wendling
74671a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner        SPAdj += Size;
747405abffd5eb1ad1841491e51943b598c935f309bBill Wendling
7485e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner        MachineBasicBlock::iterator PrevI = BB->end();
7495e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner        if (I != BB->begin()) PrevI = prior(I);
75071a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner        TRI.eliminateCallFramePseudoInstr(Fn, *BB, I);
751405abffd5eb1ad1841491e51943b598c935f309bBill Wendling
75271a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner        // Visit the instructions created by eliminateCallFramePseudoInstr().
7535e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner        if (PrevI == BB->end())
7545e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner          I = BB->begin();     // The replaced instr was the first in the block.
7555e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner        else
7567896c9f436a4eda5ec15e882a7505ba482a2fcd0Chris Lattner          I = llvm::next(PrevI);
75771a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner        continue;
7588e3347332120956538a6d882b02719e34b57f0cdEvan Cheng      }
759988a5782d3ce3cddc65d57d6aac7312d33ed59abBill Wendling
76078a5bd5dbd4d99d916c69d89ceaabd83c0e52469Evan Cheng      MachineInstr *MI = I;
761405abffd5eb1ad1841491e51943b598c935f309bBill Wendling      bool DoIncr = true;
762405abffd5eb1ad1841491e51943b598c935f309bBill Wendling      for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i)
763d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman        if (MI->getOperand(i).isFI()) {
76471a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner          // Some instructions (e.g. inline asm instructions) can have
76571a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner          // multiple frame indices and/or cause eliminateFrameIndex
76671a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner          // to insert more than one instruction. We need the register
76771a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner          // scavenger to go through all of these instructions so that
76871a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner          // it can update its register information. We keep the
76971a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner          // iterator at the point before insertion so that we can
77071a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner          // revisit them in full.
77171a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner          bool AtBeginning = (I == BB->begin());
77271a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner          if (!AtBeginning) --I;
77371a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner
77471a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner          // If this instruction has a FrameIndex operand, we need to
77571a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner          // use that target machine register info object to eliminate
77671a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner          // it.
7770ed257c0365f1e2227ccd9f42c2ae1f80815d6d2Jim Grosbach          TRI.eliminateFrameIndex(MI, SPAdj,
7780ed257c0365f1e2227ccd9f42c2ae1f80815d6d2Jim Grosbach                                  FrameIndexVirtualScavenging ?  NULL : RS);
77971a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner
78071a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner          // Reset the iterator if we were at the beginning of the BB.
78171a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner          if (AtBeginning) {
78271a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner            I = BB->begin();
78371a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner            DoIncr = false;
78471a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner          }
78571a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner
78671a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner          MI = 0;
78771a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner          break;
78871a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner        }
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.
8093d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbachvoid PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) {
8103d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach  // Run through the instructions and find any virtual registers.
8113d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach  for (MachineFunction::iterator BB = Fn.begin(),
8123d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach       E = Fn.end(); BB != E; ++BB) {
8133d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach    RS->enterBasicBlock(BB);
8143d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach
815700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach    unsigned VirtReg = 0;
816700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach    unsigned ScratchReg = 0;
817e40bf5f9f40a4672cd55bfa51c64a4bb6f4b2f8fJim Grosbach    int SPAdj = 0;
8183d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach
819b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbach    // The instruction stream may change in the loop, so check BB->end()
820b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbach    // directly.
821332553768242e82383df61d9161d1a665bfb3122Jim Grosbach    for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) {
8223d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach      MachineInstr *MI = I;
823332553768242e82383df61d9161d1a665bfb3122Jim Grosbach      for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
8243d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach        if (MI->getOperand(i).isReg()) {
825b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbach          MachineOperand &MO = MI->getOperand(i);
826b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbach          unsigned Reg = MO.getReg();
82732030fe021ee614df6fdd77a2228e0e265049f3dJim Grosbach          if (Reg == 0)
8289a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach            continue;
829700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach          if (!TargetRegisterInfo::isVirtualRegister(Reg))
83032030fe021ee614df6fdd77a2228e0e265049f3dJim Grosbach            continue;
831c52b3cced8aebbc665021ec6b8bcd0974c4ad7aeJim Grosbach
832700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach          ++NumVirtualFrameRegs;
8339a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach
834e40bf5f9f40a4672cd55bfa51c64a4bb6f4b2f8fJim Grosbach          // Have we already allocated a scratch register for this virtual?
835700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach          if (Reg != VirtReg) {
836e40bf5f9f40a4672cd55bfa51c64a4bb6f4b2f8fJim Grosbach            // When we first encounter a new virtual register, it
837e40bf5f9f40a4672cd55bfa51c64a4bb6f4b2f8fJim Grosbach            // must be a definition.
838e40bf5f9f40a4672cd55bfa51c64a4bb6f4b2f8fJim Grosbach            assert(MI->getOperand(i).isDef() &&
839e40bf5f9f40a4672cd55bfa51c64a4bb6f4b2f8fJim Grosbach                   "frame index virtual missing def!");
840332553768242e82383df61d9161d1a665bfb3122Jim Grosbach            // Scavenge a new scratch register
841700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach            VirtReg = Reg;
842332553768242e82383df61d9161d1a665bfb3122Jim Grosbach            const TargetRegisterClass *RC = Fn.getRegInfo().getRegClass(Reg);
843700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach            ScratchReg = RS->scavengeRegister(RC, I, SPAdj);
844c52b3cced8aebbc665021ec6b8bcd0974c4ad7aeJim Grosbach            ++NumScavengedRegs;
8453d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach          }
846c0c7c2b6061e7ca2d528bbedadb1bea0561c9158Jim Grosbach          // Replace this reference to the virtual register with the
847332553768242e82383df61d9161d1a665bfb3122Jim Grosbach          // scratch register.
848700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach          assert (ScratchReg && "Missing scratch register!");
849700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach          MI->getOperand(i).setReg(ScratchReg);
8509a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach
8513d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach        }
852332553768242e82383df61d9161d1a665bfb3122Jim Grosbach      }
8530f657b156f3d0890584bedda7294932a20b2ea16Jim Grosbach      RS->forward(I);
8540f657b156f3d0890584bedda7294932a20b2ea16Jim Grosbach      ++I;
8553d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach    }
8563d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach  }
8573d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach}
858