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