PrologEpilogInserter.cpp revision dc3beb90178fc316f63790812b22201884eaa017
158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner//===-- PrologEpilogInserter.cpp - Insert Prolog/Epilog code in function --===// 2edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman// 3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// The LLVM Compiler Infrastructure 4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman// 8b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//===----------------------------------------------------------------------===// 958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner// 1058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner// This pass is responsible for finalizing the functions frame layout, saving 1158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner// callee saved registers, and for emitting prolog & epilog code for the 1258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner// function. 1358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner// 1458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner// This pass must be run after register allocation. After this pass is 1558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner// executed, it is illegal to construct MO_FrameIndex operands. 1658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner// 17378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby// This pass provides an optional shrink wrapping variant of prolog/epilog 18378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby// insertion, enabled via --shrink-wrap. See ShrinkWrapping.cpp. 19ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby// 2058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner//===----------------------------------------------------------------------===// 2158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 223d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#define DEBUG_TYPE "pei" 23752c1df73949438ef6fa86a86363ee7091aa2532John Mosby#include "PrologEpilogInserter.h" 24d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/IndexedMap.h" 25d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/STLExtras.h" 26d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/SmallSet.h" 27d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/Statistic.h" 28ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby#include "llvm/CodeGen/MachineDominators.h" 29eb24db9727a7babe863d5afe70c7bda3a460da18Chris Lattner#include "llvm/CodeGen/MachineFrameInfo.h" 30d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineInstr.h" 31d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineLoopInfo.h" 3284bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner#include "llvm/CodeGen/MachineRegisterInfo.h" 3349dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng#include "llvm/CodeGen/RegisterScavenging.h" 340b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/InlineAsm.h" 353d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach#include "llvm/Support/CommandLine.h" 36a4f0b3a084d120cfc5b5bb06f64b222f5cb72740Chris Lattner#include "llvm/Support/Compiler.h" 373d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/Support/Debug.h" 38d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetFrameLowering.h" 39d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetInstrInfo.h" 40d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetMachine.h" 41d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetRegisterInfo.h" 42c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng#include <climits> 43ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 4405d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattnerusing namespace llvm; 45d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 46378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosbychar PEI::ID = 0; 471dd8c8560d45d36a8e507cd014352f1d313f9f9eAndrew Trickchar &llvm::PrologEpilogCodeInserterID = PEI::ID; 48b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 492ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_BEGIN(PEI, "prologepilog", 502ab36d350293c77fc8941ce1023e4899df7e3a82Owen Anderson "Prologue/Epilogue Insertion", false, false) 512ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) 522ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) 5325600cf50df79a6e7f8365a3ca7e940592e8ca74Andrew TrickINITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 542ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_END(PEI, "prologepilog", 551dd8c8560d45d36a8e507cd014352f1d313f9f9eAndrew Trick "Prologue/Epilogue Insertion & Frame Finalization", 561dd8c8560d45d36a8e507cd014352f1d313f9f9eAndrew Trick false, false) 57b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 58c52b3cced8aebbc665021ec6b8bcd0974c4ad7aeJim GrosbachSTATISTIC(NumVirtualFrameRegs, "Number of virtual frame regs encountered"); 59c52b3cced8aebbc665021ec6b8bcd0974c4ad7aeJim GrosbachSTATISTIC(NumScavengedRegs, "Number of frame index regs scavenged"); 60b10946a5a938a433ca4d7301b8b5ff5a8c11a7ffEvan ChengSTATISTIC(NumBytesStackSpace, 61b10946a5a938a433ca4d7301b8b5ff5a8c11a7ffEvan Cheng "Number of bytes used for stack in all functions"); 62c52b3cced8aebbc665021ec6b8bcd0974c4ad7aeJim Grosbach 63378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby/// runOnMachineFunction - Insert prolog/epilog code and replace abstract 64378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby/// frame indexes with appropriate references. 65b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby/// 66378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosbybool PEI::runOnMachineFunction(MachineFunction &Fn) { 67c5ec8a78ea898087ad361e5b755f74a76150e5fdAnton Korobeynikov const Function* F = Fn.getFunction(); 68b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo(); 6916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering *TFI = Fn.getTarget().getFrameLowering(); 7094c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 7119273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick assert(!Fn.getRegInfo().getNumVirtRegs() && "Regalloc must assign all vregs"); 7219273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick 73378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby RS = TRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : NULL; 7465c58daa8b8985d2116216043103009815a55e77Jim Grosbach FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(Fn); 75378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 76b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling // Calculate the MaxCallFrameSize and AdjustsStack variables for the 77b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling // function's frame information. Also eliminates call frame pseudo 78b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling // instructions. 7933b350bf24be396a127c81af045468765731afc7Anton Korobeynikov calculateCallsInformation(Fn); 8033b350bf24be396a127c81af045468765731afc7Anton Korobeynikov 81378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // Allow the target machine to make some adjustments to the function 82378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // e.g. UsedPhysRegs before calculateCalleeSavedRegisters. 8394c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov TFI->processFunctionBeforeCalleeSavedScan(Fn, RS); 84378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 8533b350bf24be396a127c81af045468765731afc7Anton Korobeynikov // Scan the function for modified callee saved registers and insert spill code 8633b350bf24be396a127c81af045468765731afc7Anton Korobeynikov // for any callee saved registers that are modified. 87378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby calculateCalleeSavedRegisters(Fn); 88378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 89378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // Determine placement of CSR spill/restore code: 905b02901e91a155feca84d7383c1e569aacd1739eJim Grosbach // - With shrink wrapping, place spills and restores to tightly 91378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // enclose regions in the Machine CFG of the function where 925b02901e91a155feca84d7383c1e569aacd1739eJim Grosbach // they are used. 935b02901e91a155feca84d7383c1e569aacd1739eJim Grosbach // - Without shink wrapping (default), place all spills in the 94378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // entry block, all restores in return blocks. 95378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby placeCSRSpillsAndRestores(Fn); 96378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 97378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // Add the code to save and restore the callee saved registers 98831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling if (!F->getAttributes().hasAttribute(AttributeSet::FunctionIndex, 99831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling Attribute::Naked)) 100c5ec8a78ea898087ad361e5b755f74a76150e5fdAnton Korobeynikov insertCSRSpillsAndRestores(Fn); 101378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 102378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // Allow the target machine to make final modifications to the function 103378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // before the frame layout is finalized. 1043080d23fde4981835d8a7faf46c152441fadb11fHal Finkel TFI->processFunctionBeforeFrameFinalized(Fn, RS); 105378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 106378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // Calculate actual frame offsets for all abstract stack objects... 107378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby calculateFrameObjectOffsets(Fn); 108378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 109378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // Add prolog and epilog code to the function. This function is required 110378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // to align the stack frame as necessary for any stack variables or 111b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling // called functions. Because of this, calculateCalleeSavedRegisters() 112b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling // must be called before this function in order to set the AdjustsStack 113378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // and MaxCallFrameSize variables. 114831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling if (!F->getAttributes().hasAttribute(AttributeSet::FunctionIndex, 115831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling Attribute::Naked)) 116c5ec8a78ea898087ad361e5b755f74a76150e5fdAnton Korobeynikov insertPrologEpilogCode(Fn); 117378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 118378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // Replace all MO_FrameIndex operands with physical register references 119378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // and actual offsets. 120378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // 121378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby replaceFrameIndices(Fn); 122b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 1233d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach // If register scavenging is needed, as we've enabled doing it as a 1243d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach // post-pass, scavenge the virtual registers that frame index elimiation 1253d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach // inserted. 1263d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach if (TRI->requiresRegisterScavenging(Fn) && FrameIndexVirtualScavenging) 1273d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach scavengeFrameVirtualRegs(Fn); 1283d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach 12919273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick // Clear any vregs created by virtual scavenging. 13019273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick Fn.getRegInfo().clearVirtRegs(); 13119273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick 132378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby delete RS; 133378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby clearAllSets(); 134b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby return true; 135ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby} 136ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 137b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling/// calculateCallsInformation - Calculate the MaxCallFrameSize and AdjustsStack 13833b350bf24be396a127c81af045468765731afc7Anton Korobeynikov/// variables for the function's frame information and eliminate call frame 13933b350bf24be396a127c81af045468765731afc7Anton Korobeynikov/// pseudo instructions. 14033b350bf24be396a127c81af045468765731afc7Anton Korobeynikovvoid PEI::calculateCallsInformation(MachineFunction &Fn) { 141d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); 14216c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering *TFI = Fn.getTarget().getFrameLowering(); 1439e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman MachineFrameInfo *MFI = Fn.getFrameInfo(); 14458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 14533b350bf24be396a127c81af045468765731afc7Anton Korobeynikov unsigned MaxCallFrameSize = 0; 146b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling bool AdjustsStack = MFI->adjustsStack(); 14758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 14858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Get the function call frame set-up and tear-down instruction opcode 149d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng int FrameSetupOpcode = TII.getCallFrameSetupOpcode(); 150d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng int FrameDestroyOpcode = TII.getCallFrameDestroyOpcode(); 15158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 15233b350bf24be396a127c81af045468765731afc7Anton Korobeynikov // Early exit for targets which have no call frame setup/destroy pseudo 15333b350bf24be396a127c81af045468765731afc7Anton Korobeynikov // instructions. 15433b350bf24be396a127c81af045468765731afc7Anton Korobeynikov if (FrameSetupOpcode == -1 && FrameDestroyOpcode == -1) 15558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner return; 15658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 1575c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng std::vector<MachineBasicBlock::iterator> FrameSDOps; 15858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) 1595c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) 160c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos if (I->getOpcode() == FrameSetupOpcode || 161d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner I->getOpcode() == FrameDestroyOpcode) { 1622a82ef317c39ac436f80854c7ddbb06bfddeada1Chris Lattner assert(I->getNumOperands() >= 1 && "Call Frame Setup/Destroy Pseudo" 163d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner " instructions should have a single immediate argument!"); 1649e3304900ff69c4920fea7369c9c36916c4a6a6aChris Lattner unsigned Size = I->getOperand(0).getImm(); 165d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner if (Size > MaxCallFrameSize) MaxCallFrameSize = Size; 166b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling AdjustsStack = true; 1675c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng FrameSDOps.push_back(I); 168518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner } else if (I->isInlineAsm()) { 169f1e309eb4862459a76445942ba4dafc433b6f317Dale Johannesen // Some inline asm's need a stack frame, as indicated by operand 1. 170c36b7069b42bece963b7e6adf020353ce990ef76Evan Cheng unsigned ExtraInfo = I->getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 171c36b7069b42bece963b7e6adf020353ce990ef76Evan Cheng if (ExtraInfo & InlineAsm::Extra_IsAlignStack) 172f1e309eb4862459a76445942ba4dafc433b6f317Dale Johannesen AdjustsStack = true; 17358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 17458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 175b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling MFI->setAdjustsStack(AdjustsStack); 1769e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman MFI->setMaxCallFrameSize(MaxCallFrameSize); 1778e3347332120956538a6d882b02719e34b57f0cdEvan Cheng 178058a024eb7265239d527680b0a448cdb48102a46Bill Wendling for (std::vector<MachineBasicBlock::iterator>::iterator 179058a024eb7265239d527680b0a448cdb48102a46Bill Wendling i = FrameSDOps.begin(), e = FrameSDOps.end(); i != e; ++i) { 180058a024eb7265239d527680b0a448cdb48102a46Bill Wendling MachineBasicBlock::iterator I = *i; 181058a024eb7265239d527680b0a448cdb48102a46Bill Wendling 182058a024eb7265239d527680b0a448cdb48102a46Bill Wendling // If call frames are not being included as part of the stack frame, and 1834642ad3af1cf508ac320b9afd25b065f08b36574Jim Grosbach // the target doesn't indicate otherwise, remove the call frame pseudos 1844642ad3af1cf508ac320b9afd25b065f08b36574Jim Grosbach // here. The sub/add sp instruction pairs are still inserted, but we don't 1854642ad3af1cf508ac320b9afd25b065f08b36574Jim Grosbach // need to track the SP adjustment for frame index elimination. 186d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (TFI->canSimplifyCallFramePseudos(Fn)) 187700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky TFI->eliminateCallFramePseudoInstr(Fn, *I->getParent(), I); 1885c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng } 18933b350bf24be396a127c81af045468765731afc7Anton Korobeynikov} 19033b350bf24be396a127c81af045468765731afc7Anton Korobeynikov 19133b350bf24be396a127c81af045468765731afc7Anton Korobeynikov 19233b350bf24be396a127c81af045468765731afc7Anton Korobeynikov/// calculateCalleeSavedRegisters - Scan the function for modified callee saved 19333b350bf24be396a127c81af045468765731afc7Anton Korobeynikov/// registers. 194831737d329a727f53a1fb0572f7b7a8127208881Bill Wendlingvoid PEI::calculateCalleeSavedRegisters(MachineFunction &F) { 195831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling const TargetRegisterInfo *RegInfo = F.getTarget().getRegisterInfo(); 196831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling const TargetFrameLowering *TFI = F.getTarget().getFrameLowering(); 197831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling MachineFrameInfo *MFI = F.getFrameInfo(); 19833b350bf24be396a127c81af045468765731afc7Anton Korobeynikov 19933b350bf24be396a127c81af045468765731afc7Anton Korobeynikov // Get the callee saved register list... 200831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling const uint16_t *CSRegs = RegInfo->getCalleeSavedRegs(&F); 20133b350bf24be396a127c81af045468765731afc7Anton Korobeynikov 20233b350bf24be396a127c81af045468765731afc7Anton Korobeynikov // These are used to keep track the callee-save area. Initialize them. 20333b350bf24be396a127c81af045468765731afc7Anton Korobeynikov MinCSFrameIndex = INT_MAX; 20433b350bf24be396a127c81af045468765731afc7Anton Korobeynikov MaxCSFrameIndex = 0; 20533b350bf24be396a127c81af045468765731afc7Anton Korobeynikov 20633b350bf24be396a127c81af045468765731afc7Anton Korobeynikov // Early exit for targets which have no callee saved registers. 20733b350bf24be396a127c81af045468765731afc7Anton Korobeynikov if (CSRegs == 0 || CSRegs[0] == 0) 20833b350bf24be396a127c81af045468765731afc7Anton Korobeynikov return; 20958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 2108c5358c93675b009ba2d57c3a5980f6bc58ba536Dale Johannesen // In Naked functions we aren't going to save any registers. 211831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling if (F.getFunction()->getAttributes().hasAttribute(AttributeSet::FunctionIndex, 212831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling Attribute::Naked)) 2138c5358c93675b009ba2d57c3a5980f6bc58ba536Dale Johannesen return; 2148c5358c93675b009ba2d57c3a5980f6bc58ba536Dale Johannesen 21508ede262a744f99429658fadb43662441bdcb42dJim Laskey std::vector<CalleeSavedInfo> CSI; 21658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner for (unsigned i = 0; CSRegs[i]; ++i) { 21758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner unsigned Reg = CSRegs[i]; 218831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling if (F.getRegInfo().isPhysRegUsed(Reg)) { 219058a024eb7265239d527680b0a448cdb48102a46Bill Wendling // If the reg is modified, save it! 22042d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola CSI.push_back(CalleeSavedInfo(Reg)); 22173ff5120eb8b8c0ccbfed8a17f1024c67a75f319Alkis Evlogimenos } 22258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 22358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 224f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey if (CSI.empty()) 225c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng return; // Early exit if no callee saved registers are modified! 22658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 227c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner unsigned NumFixedSpillSlots; 22816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering::SpillSlot *FixedSpillSlots = 229ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng TFI->getCalleeSavedSpillSlots(NumFixedSpillSlots); 230c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 23158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Now that we know which registers need to be saved and restored, allocate 23258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // stack slots for them. 233058a024eb7265239d527680b0a448cdb48102a46Bill Wendling for (std::vector<CalleeSavedInfo>::iterator 234058a024eb7265239d527680b0a448cdb48102a46Bill Wendling I = CSI.begin(), E = CSI.end(); I != E; ++I) { 235058a024eb7265239d527680b0a448cdb48102a46Bill Wendling unsigned Reg = I->getReg(); 23642d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola const TargetRegisterClass *RC = RegInfo->getMinimalPhysRegClass(Reg); 237c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 238910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng int FrameIdx; 239831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling if (RegInfo->hasReservedSpillSlot(F, Reg, FrameIdx)) { 240910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng I->setFrameIdx(FrameIdx); 241910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng continue; 242910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng } 243910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng 244c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // Check to see if this physreg must be spilled to a particular stack slot 245c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // on this target. 24616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering::SpillSlot *FixedSlot = FixedSpillSlots; 247c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner while (FixedSlot != FixedSpillSlots+NumFixedSpillSlots && 2488ff95de83cbe85d939535d2f4fb5f9b2b721081aTilmann Scheller FixedSlot->Reg != Reg) 249c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner ++FixedSlot; 250c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 251058a024eb7265239d527680b0a448cdb48102a46Bill Wendling if (FixedSlot == FixedSpillSlots + NumFixedSpillSlots) { 252c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // Nope, just spill it anywhere convenient. 2535feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng unsigned Align = RC->getAlignment(); 2545feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng unsigned StackAlign = TFI->getStackAlignment(); 255058a024eb7265239d527680b0a448cdb48102a46Bill Wendling 256058a024eb7265239d527680b0a448cdb48102a46Bill Wendling // We may not be able to satisfy the desired alignment specification of 257058a024eb7265239d527680b0a448cdb48102a46Bill Wendling // the TargetRegisterClass if the stack alignment is smaller. Use the 258058a024eb7265239d527680b0a448cdb48102a46Bill Wendling // min. 2595feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng Align = std::min(Align, StackAlign); 2609e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman FrameIdx = MFI->CreateStackObject(RC->getSize(), Align, true); 261c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng if ((unsigned)FrameIdx < MinCSFrameIndex) MinCSFrameIndex = FrameIdx; 262c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng if ((unsigned)FrameIdx > MaxCSFrameIndex) MaxCSFrameIndex = FrameIdx; 263c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner } else { 264c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // Spill it to the stack where we must. 265ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng FrameIdx = MFI->CreateFixedObject(RC->getSize(), FixedSlot->Offset, true); 266c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner } 267058a024eb7265239d527680b0a448cdb48102a46Bill Wendling 268058a024eb7265239d527680b0a448cdb48102a46Bill Wendling I->setFrameIdx(FrameIdx); 26958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 27008ede262a744f99429658fadb43662441bdcb42dJim Laskey 2719e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman MFI->setCalleeSavedInfo(CSI); 272c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner} 273c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 274ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby/// insertCSRSpillsAndRestores - Insert spill and restore code for 275ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby/// callee saved registers used in the function, handling shrink wrapping. 276c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner/// 277ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosbyvoid PEI::insertCSRSpillsAndRestores(MachineFunction &Fn) { 278f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey // Get callee saved register information. 2799e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman MachineFrameInfo *MFI = Fn.getFrameInfo(); 2809e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 281ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 2829e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman MFI->setCalleeSavedInfoValid(true); 283d62c9a697b53f9e754926a89126fd121220ed09bJakob Stoklund Olesen 284c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Early exit if no callee saved registers are modified! 285f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey if (CSI.empty()) 286edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman return; 287c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 288f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); 28916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering *TFI = Fn.getTarget().getFrameLowering(); 290746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo(); 291ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby MachineBasicBlock::iterator I; 29200dff8dda29b5a249cd99405ce26e84cef13ba53Evan Cheng 29306a23ea8083657270e86a178abf050246caac0b5Chad Rosier if (!ShrinkWrapThisFunction) { 294b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // Spill using target interface. 295b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby I = EntryBlock->begin(); 296cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov if (!TFI->spillCalleeSavedRegisters(*EntryBlock, I, CSI, TRI)) { 297b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 298ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // Add the callee-saved register as live-in. 299ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // It's killed at the spill. 300b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby EntryBlock->addLiveIn(CSI[i].getReg()); 301ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 302ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // Insert the spill to the stack frame. 30342d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola unsigned Reg = CSI[i].getReg(); 30442d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 30542d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola TII.storeRegToStackSlot(*EntryBlock, I, Reg, true, 30642d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola CSI[i].getFrameIdx(), RC, TRI); 307ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby } 308ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng } 309ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 310b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // Restore using target interface. 311b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby for (unsigned ri = 0, re = ReturnBlocks.size(); ri != re; ++ri) { 312b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby MachineBasicBlock* MBB = ReturnBlocks[ri]; 313c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos I = MBB->end(); --I; 31458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 315f7c094000f4baf094b1d60ba68a5b4e0193c502aBill Wendling // Skip over all terminator instructions, which are part of the return 3164fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner // sequence. 3174fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner MachineBasicBlock::iterator I2 = I; 3185a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng while (I2 != MBB->begin() && (--I2)->isTerminator()) 3194fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner I = I2; 3204fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner 321dfd58709cc78e841ef4a50ba75d940473031617eChris Lattner bool AtStart = I == MBB->begin(); 322ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner MachineBasicBlock::iterator BeforeI = I; 323ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner if (!AtStart) 324ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner --BeforeI; 325ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 326ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // Restore all registers immediately before the return and any 3277a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // terminators that precede it. 328cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov if (!TFI->restoreCalleeSavedRegisters(*MBB, I, CSI, TRI)) { 329ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 33042d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola unsigned Reg = CSI[i].getReg(); 33142d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 33242d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola TII.loadRegFromStackSlot(*MBB, I, Reg, 333ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby CSI[i].getFrameIdx(), 33442d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola RC, TRI); 335ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng assert(I != MBB->begin() && 336ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng "loadRegFromStackSlot didn't insert any code!"); 337ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // Insert in reverse order. loadRegFromStackSlot can insert 338ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // multiple instructions. 339ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng if (AtStart) 340ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng I = MBB->begin(); 341ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng else { 342ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng I = BeforeI; 343ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng ++I; 344ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng } 345ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner } 34658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 347b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } 348b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby return; 349b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } 350ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 351b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // Insert spills. 352b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby std::vector<CalleeSavedInfo> blockCSI; 353b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby for (CSRegBlockMap::iterator BI = CSRSave.begin(), 354b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby BE = CSRSave.end(); BI != BE; ++BI) { 355b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby MachineBasicBlock* MBB = BI->first; 356b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby CSRegSet save = BI->second; 357ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 358b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby if (save.empty()) 359b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby continue; 360ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 361b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby blockCSI.clear(); 362b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby for (CSRegSet::iterator RI = save.begin(), 363b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby RE = save.end(); RI != RE; ++RI) { 364b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby blockCSI.push_back(CSI[*RI]); 365b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } 366b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby assert(blockCSI.size() > 0 && 367b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby "Could not collect callee saved register info"); 368b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 369b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby I = MBB->begin(); 370b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 371b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // When shrink wrapping, use stack slot stores/loads. 372b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby for (unsigned i = 0, e = blockCSI.size(); i != e; ++i) { 373b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // Add the callee-saved register as live-in. 374b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // It's killed at the spill. 375b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby MBB->addLiveIn(blockCSI[i].getReg()); 376b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 377b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // Insert the spill to the stack frame. 37842d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola unsigned Reg = blockCSI[i].getReg(); 37942d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 38042d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola TII.storeRegToStackSlot(*MBB, I, Reg, 381b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby true, 382b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby blockCSI[i].getFrameIdx(), 38342d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola RC, TRI); 384b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } 385b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } 386b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 387b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby for (CSRegBlockMap::iterator BI = CSRRestore.begin(), 388b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby BE = CSRRestore.end(); BI != BE; ++BI) { 389b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby MachineBasicBlock* MBB = BI->first; 390b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby CSRegSet restore = BI->second; 391b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 392b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby if (restore.empty()) 393b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby continue; 394b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 395b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby blockCSI.clear(); 396b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby for (CSRegSet::iterator RI = restore.begin(), 397b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby RE = restore.end(); RI != RE; ++RI) { 398b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby blockCSI.push_back(CSI[*RI]); 399b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } 400b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby assert(blockCSI.size() > 0 && 401b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby "Could not find callee saved register info"); 402b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 403b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // If MBB is empty and needs restores, insert at the _beginning_. 404b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby if (MBB->empty()) { 405b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby I = MBB->begin(); 406b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } else { 407b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby I = MBB->end(); 408b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby --I; 409b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 410b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // Skip over all terminator instructions, which are part of the 411b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // return sequence. 4125a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng if (! I->isTerminator()) { 413b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby ++I; 414ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby } else { 415b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby MachineBasicBlock::iterator I2 = I; 4165a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng while (I2 != MBB->begin() && (--I2)->isTerminator()) 417b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby I = I2; 418ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby } 419b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } 420ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 421b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby bool AtStart = I == MBB->begin(); 422b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby MachineBasicBlock::iterator BeforeI = I; 423b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby if (!AtStart) 424b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby --BeforeI; 425b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 426b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // Restore all registers immediately before the return and any 4277a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // terminators that precede it. 428b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby for (unsigned i = 0, e = blockCSI.size(); i != e; ++i) { 42942d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola unsigned Reg = blockCSI[i].getReg(); 43042d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 43142d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola TII.loadRegFromStackSlot(*MBB, I, Reg, 432b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby blockCSI[i].getFrameIdx(), 43342d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola RC, TRI); 434b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby assert(I != MBB->begin() && 435b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby "loadRegFromStackSlot didn't insert any code!"); 436b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // Insert in reverse order. loadRegFromStackSlot can insert 437b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // multiple instructions. 438b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby if (AtStart) 439b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby I = MBB->begin(); 440b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby else { 441b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby I = BeforeI; 442b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby ++I; 443ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby } 44458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 445ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby } 44658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner} 44758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 448cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling/// AdjustStackOffset - Helper function used to adjust the stack frame offset. 449cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendlingstatic inline void 4509e9aa44d1a33fb845268ba07b726a31f26195690Dan GohmanAdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx, 451cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling bool StackGrowsDown, int64_t &Offset, 452cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling unsigned &MaxAlign) { 45394188d4e67cf1c570ad87dbabf198931033d628eBob Wilson // If the stack grows down, add the object size to find the lowest address. 454cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling if (StackGrowsDown) 4559e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman Offset += MFI->getObjectSize(FrameIdx); 456cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling 4579e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman unsigned Align = MFI->getObjectAlignment(FrameIdx); 458cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling 459cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling // If the alignment of this object is greater than that of the stack, then 460cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling // increase the stack alignment to match. 461cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling MaxAlign = std::max(MaxAlign, Align); 462cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling 463cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling // Adjust to alignment boundary. 464cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling Offset = (Offset + Align - 1) / Align * Align; 465cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling 466cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling if (StackGrowsDown) { 4673d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << -Offset << "]\n"); 4689e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman MFI->setObjectOffset(FrameIdx, -Offset); // Set the computed offset 469cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling } else { 4703d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << Offset << "]\n"); 4719e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman MFI->setObjectOffset(FrameIdx, Offset); 4729e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman Offset += MFI->getObjectSize(FrameIdx); 473cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling } 474cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling} 47558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 47658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the 47792b9fcea7b3180ed18f379212d14bd5cea7a1954Chris Lattner/// abstract stack objects. 47858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// 47958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattnervoid PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { 48016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering &TFI = *Fn.getTarget().getFrameLowering(); 481edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 48258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner bool StackGrowsDown = 48316c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown; 484edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 48558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Loop over all of the stack objects, assigning sequential addresses... 4869e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman MachineFrameInfo *MFI = Fn.getFrameInfo(); 48758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 48805d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner // Start at the beginning of the local area. 489577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // The Offset is the distance from the stack top in the direction 490c0d6012b31afa2220306afa27db1b02e18427776Dan Gohman // of stack growth -- so it's always nonnegative. 491c34666ee1871d47dfa4865c7138902dd1b770101Bob Wilson int LocalAreaOffset = TFI.getOffsetOfLocalArea(); 492577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner if (StackGrowsDown) 493c34666ee1871d47dfa4865c7138902dd1b770101Bob Wilson LocalAreaOffset = -LocalAreaOffset; 494c34666ee1871d47dfa4865c7138902dd1b770101Bob Wilson assert(LocalAreaOffset >= 0 495577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner && "Local area offset should be in direction of stack growth"); 496c34666ee1871d47dfa4865c7138902dd1b770101Bob Wilson int64_t Offset = LocalAreaOffset; 497577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner 498577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // If there are fixed sized objects that are preallocated in the local area, 499577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // non-fixed objects can't be allocated right at the start of local area. 500ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // We currently don't support filling in holes in between fixed sized 501ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // objects, so we adjust 'Offset' to point to the end of last fixed sized 50205d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner // preallocated object. 5039e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman for (int i = MFI->getObjectIndexBegin(); i != 0; ++i) { 504a401b1e1c5eb9563617db8a2477b4c5f8b239521Chris Lattner int64_t FixedOff; 505577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner if (StackGrowsDown) { 506577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // The maximum distance from the stack pointer is at lower address of 507577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // the object -- which is given by offset. For down growing stack 508577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // the offset is negative, so we negate the offset to get the distance. 5099e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman FixedOff = -MFI->getObjectOffset(i); 510577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner } else { 511edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman // The maximum distance from the start pointer is at the upper 512577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // address of the object. 5139e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman FixedOff = MFI->getObjectOffset(i) + MFI->getObjectSize(i); 514edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman } 515edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman if (FixedOff > Offset) Offset = FixedOff; 51605d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner } 51705d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner 518c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // First assign frame offsets to stack objects that are used to spill 519ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng // callee saved registers. 520c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng if (StackGrowsDown) { 5215c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng for (unsigned i = MinCSFrameIndex; i <= MaxCSFrameIndex; ++i) { 522b4c14aaa50b58ac723d0ed179695e1cd7296572aEric Christopher // If the stack grows down, we need to add the size to find the lowest 523c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // address of the object. 5249e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman Offset += MFI->getObjectSize(i); 525c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 5269e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman unsigned Align = MFI->getObjectAlignment(i); 527c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Adjust to alignment boundary 528c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng Offset = (Offset+Align-1)/Align*Align; 529c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 5309e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman MFI->setObjectOffset(i, -Offset); // Set the computed offset 531c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng } 532c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng } else { 533a8c63f0fc9feb48f17d702a907f065959c41e337Bruno Cardoso Lopes int MaxCSFI = MaxCSFrameIndex, MinCSFI = MinCSFrameIndex; 534a8c63f0fc9feb48f17d702a907f065959c41e337Bruno Cardoso Lopes for (int i = MaxCSFI; i >= MinCSFI ; --i) { 5359e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman unsigned Align = MFI->getObjectAlignment(i); 536c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Adjust to alignment boundary 537c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng Offset = (Offset+Align-1)/Align*Align; 538c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 5399e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman MFI->setObjectOffset(i, Offset); 5409e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman Offset += MFI->getObjectSize(i); 541c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng } 542c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng } 543c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 5449e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman unsigned MaxAlign = MFI->getMaxAlignment(); 5457545f49a5edfe19612d03e683d8b955c03018056Evan Cheng 54687f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // Make sure the special register scavenging spill slot is closest to the 54787f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // frame pointer if a frame pointer is required. 5486f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); 5490f657b156f3d0890584bedda7294932a20b2ea16Jim Grosbach if (RS && TFI.hasFP(Fn) && RegInfo->useFPForScavengingIndex(Fn) && 5500f657b156f3d0890584bedda7294932a20b2ea16Jim Grosbach !RegInfo->needsStackRealignment(Fn)) { 551dc3beb90178fc316f63790812b22201884eaa017Hal Finkel SmallVector<int, 2> SFIs; 552dc3beb90178fc316f63790812b22201884eaa017Hal Finkel RS->getScavengingFrameIndices(SFIs); 553dc3beb90178fc316f63790812b22201884eaa017Hal Finkel for (SmallVector<int, 2>::iterator I = SFIs.begin(), 554dc3beb90178fc316f63790812b22201884eaa017Hal Finkel IE = SFIs.end(); I != IE; ++I) 555dc3beb90178fc316f63790812b22201884eaa017Hal Finkel AdjustStackOffset(MFI, *I, StackGrowsDown, Offset, MaxAlign); 55687f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng } 55787f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 5584861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach // FIXME: Once this is working, then enable flag will change to a target 5594861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach // check for whether the frame is large enough to want to use virtual 5604861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach // frame index registers. Functions which don't want/need this optimization 5614861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach // will continue to use the existing code path. 562a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach if (MFI->getUseLocalStackAllocationBlock()) { 5634861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach unsigned Align = MFI->getLocalFrameMaxAlign(); 5644861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach 5654861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach // Adjust to alignment boundary. 5664861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach Offset = (Offset + Align - 1) / Align * Align; 5674861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach 568fecdea0bf77599038eb368db3bc6a38a14900308Jim Grosbach DEBUG(dbgs() << "Local frame base offset: " << Offset << "\n"); 569fecdea0bf77599038eb368db3bc6a38a14900308Jim Grosbach 5703d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // Resolve offsets for objects in the local block. 5713d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach for (unsigned i = 0, e = MFI->getLocalFrameObjectCount(); i != e; ++i) { 5723d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach std::pair<int, int64_t> Entry = MFI->getLocalFrameObjectMap(i); 57367ff81a08319f916571cea90ed92e17015c8584fJim Grosbach int64_t FIOffset = (StackGrowsDown ? -Offset : Offset) + Entry.second; 57467ff81a08319f916571cea90ed92e17015c8584fJim Grosbach DEBUG(dbgs() << "alloc FI(" << Entry.first << ") at SP[" << 57567ff81a08319f916571cea90ed92e17015c8584fJim Grosbach FIOffset << "]\n"); 57667ff81a08319f916571cea90ed92e17015c8584fJim Grosbach MFI->setObjectOffset(Entry.first, FIOffset); 5773d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach } 57867ff81a08319f916571cea90ed92e17015c8584fJim Grosbach // Allocate the local block 57967ff81a08319f916571cea90ed92e17015c8584fJim Grosbach Offset += MFI->getLocalFrameSize(); 58067ff81a08319f916571cea90ed92e17015c8584fJim Grosbach 58167ff81a08319f916571cea90ed92e17015c8584fJim Grosbach MaxAlign = std::max(Align, MaxAlign); 5823d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach } 5833d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 584b2a4298ce41e7ef80cd75a3c1dfa6433f0759a1aBill Wendling // Make sure that the stack protector comes before the local variables on the 585b2a4298ce41e7ef80cd75a3c1dfa6433f0759a1aBill Wendling // stack. 586dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling SmallSet<int, 16> LargeStackObjs; 587dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling if (MFI->getStackProtectorIndex() >= 0) { 5889e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman AdjustStackOffset(MFI, MFI->getStackProtectorIndex(), StackGrowsDown, 589cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling Offset, MaxAlign); 590b2a4298ce41e7ef80cd75a3c1dfa6433f0759a1aBill Wendling 591dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling // Assign large stack objects first. 592dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) { 593a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach if (MFI->isObjectPreAllocated(i) && 594a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach MFI->getUseLocalStackAllocationBlock()) 5953d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach continue; 596dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex) 597dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling continue; 598dc3beb90178fc316f63790812b22201884eaa017Hal Finkel if (RS && RS->isScavengingFrameIndex((int)i)) 599dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling continue; 600dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling if (MFI->isDeadObjectIndex(i)) 601dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling continue; 602dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling if (MFI->getStackProtectorIndex() == (int)i) 603dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling continue; 604dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling if (!MFI->MayNeedStackProtector(i)) 605dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling continue; 606dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling 607dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign); 608dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling LargeStackObjs.insert(i); 609dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling } 610dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling } 611dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling 612c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Then assign frame offsets to stack objects that are not used to spill 613ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng // callee saved registers. 6149e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) { 615a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach if (MFI->isObjectPreAllocated(i) && 616a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach MFI->getUseLocalStackAllocationBlock()) 6173d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach continue; 618c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex) 619c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng continue; 620dc3beb90178fc316f63790812b22201884eaa017Hal Finkel if (RS && RS->isScavengingFrameIndex((int)i)) 62187f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng continue; 6229e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman if (MFI->isDeadObjectIndex(i)) 623d36531249a9a9500e516148e7e72d4c0a7a4d0eeEvan Cheng continue; 6249e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman if (MFI->getStackProtectorIndex() == (int)i) 62544cf38c01ff610139d2e8dbbdc4e6123a3debcddBill Wendling continue; 626dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling if (LargeStackObjs.count(i)) 627dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling continue; 628c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 6299e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign); 63058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 63158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 63287f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // Make sure the special register scavenging spill slot is closest to the 63387f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // stack pointer. 6340f657b156f3d0890584bedda7294932a20b2ea16Jim Grosbach if (RS && (!TFI.hasFP(Fn) || RegInfo->needsStackRealignment(Fn) || 6350f657b156f3d0890584bedda7294932a20b2ea16Jim Grosbach !RegInfo->useFPForScavengingIndex(Fn))) { 636dc3beb90178fc316f63790812b22201884eaa017Hal Finkel SmallVector<int, 2> SFIs; 637dc3beb90178fc316f63790812b22201884eaa017Hal Finkel RS->getScavengingFrameIndices(SFIs); 638dc3beb90178fc316f63790812b22201884eaa017Hal Finkel for (SmallVector<int, 2>::iterator I = SFIs.begin(), 639dc3beb90178fc316f63790812b22201884eaa017Hal Finkel IE = SFIs.end(); I != IE; ++I) 640dc3beb90178fc316f63790812b22201884eaa017Hal Finkel AdjustStackOffset(MFI, *I, StackGrowsDown, Offset, MaxAlign); 64187f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng } 64287f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 64333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!TFI.targetHandlesStackFrameRounding()) { 6445c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng // If we have reserved argument space for call sites in the function 6455c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng // immediately on entry to the current function, count it as part of the 6465c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng // overall stack size. 647d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (MFI->adjustsStack() && TFI.hasReservedCallFrame(Fn)) 6489e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman Offset += MFI->getMaxCallFrameSize(); 649367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng 6500035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson // Round up the size to a multiple of the alignment. If the function has 6510035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson // any calls or alloca's, align to the target's StackAlignment value to 6520035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson // ensure that the callee's frame or the alloca data is suitably aligned; 6530035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson // otherwise, for leaf functions, align to the TransientStackAlignment 6540035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson // value. 6550035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson unsigned StackAlign; 656b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling if (MFI->adjustsStack() || MFI->hasVarSizedObjects() || 6579e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman (RegInfo->needsStackRealignment(Fn) && MFI->getObjectIndexEnd() != 0)) 6580035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson StackAlign = TFI.getStackAlignment(); 6590035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson else 6600035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson StackAlign = TFI.getTransientStackAlignment(); 661b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling 662b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling // If the frame pointer is eliminated, all frame offsets will be relative to 663b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling // SP not FP. Align to MaxAlign so this works. 6640035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson StackAlign = std::max(StackAlign, MaxAlign); 6650035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson unsigned AlignMask = StackAlign - 1; 666ea84c5ee952c62dd0c703c9852d7a60715e4a435Chris Lattner Offset = (Offset + AlignMask) & ~uint64_t(AlignMask); 667367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng } 668367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng 669367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng // Update frame info to pretend that this is part of the stack... 670c219d191aadb4f9532bcaea5c5e66f66912656caJakob Stoklund Olesen int64_t StackSize = Offset - LocalAreaOffset; 671c219d191aadb4f9532bcaea5c5e66f66912656caJakob Stoklund Olesen MFI->setStackSize(StackSize); 672c219d191aadb4f9532bcaea5c5e66f66912656caJakob Stoklund Olesen NumBytesStackSpace += StackSize; 6734ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner} 6744ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner 675c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng/// insertPrologEpilogCode - Scan the function for modified callee saved 676c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng/// registers, insert spill code for these callee saved registers, then add 6774ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner/// prolog and epilog code to the function. 6784ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner/// 6794ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattnervoid PEI::insertPrologEpilogCode(MachineFunction &Fn) { 68016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering &TFI = *Fn.getTarget().getFrameLowering(); 681874384e20f618d6ac932628db64e048757213fcdAnton Korobeynikov 6824ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner // Add prologue to the function... 68333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TFI.emitPrologue(Fn); 6844ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner 6854ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner // Add epilogue to restore the callee-save registers in each exiting block 6864ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) { 6874ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner // If last instruction is a return instruction, add an epilogue 6885a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng if (!I->empty() && I->back().isReturn()) 68933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TFI.emitEpilogue(Fn, *I); 6904ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner } 69176927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 692e81abfd30b7c81735e9f3d79006c2653690aa592Rafael Espindola // Emit additional code that is required to support segmented stacks, if 693e81abfd30b7c81735e9f3d79006c2653690aa592Rafael Espindola // we've been asked for it. This, when linked with a runtime with support 694e81abfd30b7c81735e9f3d79006c2653690aa592Rafael Espindola // for segmented stacks (libgcc is one), will result in allocating stack 695e81abfd30b7c81735e9f3d79006c2653690aa592Rafael Espindola // space in small chunks instead of one large contiguous block. 6968a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky if (Fn.getTarget().Options.EnableSegmentedStacks) 69776927d758657b3a511c73467ec5a7288795c1513Rafael Espindola TFI.adjustForSegmentedStacks(Fn); 69898fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 69998fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // Emit additional code that is required to explicitly handle the stack in 70098fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // HiPE native code (if needed) when loaded in the Erlang/OTP runtime. The 70198fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // approach is rather similar to that of Segmented Stacks, but it uses a 70298fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // different conditional check and another BIF for allocating more stack 70398fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // space. 70498fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer if (Fn.getFunction()->getCallingConv() == CallingConv::HiPE) 70598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer TFI.adjustForHiPEPrologue(Fn); 70658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner} 70758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 70858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// replaceFrameIndices - Replace all MO_FrameIndex operands with physical 70958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// register references and actual offsets. 71058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// 71158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattnervoid PEI::replaceFrameIndices(MachineFunction &Fn) { 71258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner if (!Fn.getFrameInfo()->hasStackObjects()) return; // Nothing to do? 71358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 71458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner const TargetMachine &TM = Fn.getTarget(); 71558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner assert(TM.getRegisterInfo() && "TM::getRegisterInfo() must be implemented!"); 716d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); 7176f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman const TargetRegisterInfo &TRI = *TM.getRegisterInfo(); 71816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering *TFI = TM.getFrameLowering(); 7198e3347332120956538a6d882b02719e34b57f0cdEvan Cheng bool StackGrowsDown = 72016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov TFI->getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown; 721d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng int FrameSetupOpcode = TII.getCallFrameSetupOpcode(); 722d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng int FrameDestroyOpcode = TII.getCallFrameDestroyOpcode(); 72358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 724ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby for (MachineFunction::iterator BB = Fn.begin(), 725ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby E = Fn.end(); BB != E; ++BB) { 7266627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach#ifndef NDEBUG 7276627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach int SPAdjCount = 0; // frame setup / destroy count. 7286627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach#endif 7298e3347332120956538a6d882b02719e34b57f0cdEvan Cheng int SPAdj = 0; // SP offset due to call frame setup / destroy. 7303d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach if (RS && !FrameIndexVirtualScavenging) RS->enterBasicBlock(BB); 731ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 7320ebe9c132c6b9c74b334f0c7503e702b499575d5Chris Lattner for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) { 733405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 734405abffd5eb1ad1841491e51943b598c935f309bBill Wendling if (I->getOpcode() == FrameSetupOpcode || 735405abffd5eb1ad1841491e51943b598c935f309bBill Wendling I->getOpcode() == FrameDestroyOpcode) { 7366627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach#ifndef NDEBUG 7376627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach // Track whether we see even pairs of them 7386627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach SPAdjCount += I->getOpcode() == FrameSetupOpcode ? 1 : -1; 7396627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach#endif 740405abffd5eb1ad1841491e51943b598c935f309bBill Wendling // Remember how much SP has been adjusted to create the call 741405abffd5eb1ad1841491e51943b598c935f309bBill Wendling // frame. 74271a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner int Size = I->getOperand(0).getImm(); 743405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 74471a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner if ((!StackGrowsDown && I->getOpcode() == FrameSetupOpcode) || 74571a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner (StackGrowsDown && I->getOpcode() == FrameDestroyOpcode)) 74671a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner Size = -Size; 747988a5782d3ce3cddc65d57d6aac7312d33ed59abBill Wendling 74871a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner SPAdj += Size; 749405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 7505e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner MachineBasicBlock::iterator PrevI = BB->end(); 7515e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner if (I != BB->begin()) PrevI = prior(I); 752700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky TFI->eliminateCallFramePseudoInstr(Fn, *BB, I); 753405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 75471a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // Visit the instructions created by eliminateCallFramePseudoInstr(). 7555e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner if (PrevI == BB->end()) 7565e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner I = BB->begin(); // The replaced instr was the first in the block. 7575e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner else 7587896c9f436a4eda5ec15e882a7505ba482a2fcd0Chris Lattner I = llvm::next(PrevI); 75971a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner continue; 7608e3347332120956538a6d882b02719e34b57f0cdEvan Cheng } 761988a5782d3ce3cddc65d57d6aac7312d33ed59abBill Wendling 76278a5bd5dbd4d99d916c69d89ceaabd83c0e52469Evan Cheng MachineInstr *MI = I; 763405abffd5eb1ad1841491e51943b598c935f309bBill Wendling bool DoIncr = true; 7643ab115ce8f5262608630d67c28707dbd24361d03Chad Rosier for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 7655fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier if (!MI->getOperand(i).isFI()) 7665fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier continue; 7675fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier 7685fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier // Some instructions (e.g. inline asm instructions) can have 7695fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier // multiple frame indices and/or cause eliminateFrameIndex 7705fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier // to insert more than one instruction. We need the register 7715fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier // scavenger to go through all of these instructions so that 7725fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier // it can update its register information. We keep the 7735fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier // iterator at the point before insertion so that we can 7745fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier // revisit them in full. 7755fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier bool AtBeginning = (I == BB->begin()); 7765fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier if (!AtBeginning) --I; 7775fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier 7785fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier // If this instruction has a FrameIndex operand, we need to 7795fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier // use that target machine register info object to eliminate 7805fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier // it. 7815fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier TRI.eliminateFrameIndex(MI, SPAdj, i, 7825fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier FrameIndexVirtualScavenging ? NULL : RS); 7835fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier 7845fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier // Reset the iterator if we were at the beginning of the BB. 7855fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier if (AtBeginning) { 7865fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier I = BB->begin(); 7875fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier DoIncr = false; 78871a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner } 7895fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier 7905fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier MI = 0; 7915fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier break; 7923ab115ce8f5262608630d67c28707dbd24361d03Chad Rosier } 793405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 7948fc2d0ee8dd4e077ee90a1fcc36fd0101c2947a2Chris Lattner if (DoIncr && I != BB->end()) ++I; 795405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 79649dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng // Update register states. 7973d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach if (RS && !FrameIndexVirtualScavenging && MI) RS->forward(MI); 79849dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng } 799988a5782d3ce3cddc65d57d6aac7312d33ed59abBill Wendling 8006627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach // If we have evenly matched pairs of frame setup / destroy instructions, 8016627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach // make sure the adjustments come out to zero. If we don't have matched 8026627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach // pairs, we can't be sure the missing bit isn't in another basic block 8036627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach // due to a custom inserter playing tricks, so just asserting SPAdj==0 8046627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach // isn't sufficient. See tMOVCC on Thumb1, for example. 8056627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach assert((SPAdjCount || SPAdj == 0) && 8066627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach "Unbalanced call frame setup / destroy pairs?"); 80749dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng } 80858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner} 809b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 8109a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach/// scavengeFrameVirtualRegs - Replace all frame index virtual registers 8119a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach/// with physical registers. Use the register scavenger to find an 8129a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach/// appropriate register to use. 81319273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick/// 81419273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick/// FIXME: Iterating over the instruction stream is unnecessary. We can simply 81519273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick/// iterate over the vreg use list, which at this point only contains machine 81619273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick/// operands for which eliminateFrameIndex need a new scratch reg. 8173d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbachvoid PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) { 8183d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach // Run through the instructions and find any virtual registers. 8193d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach for (MachineFunction::iterator BB = Fn.begin(), 8203d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach E = Fn.end(); BB != E; ++BB) { 8213d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach RS->enterBasicBlock(BB); 8223d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach 823700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach unsigned VirtReg = 0; 824700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach unsigned ScratchReg = 0; 825e40bf5f9f40a4672cd55bfa51c64a4bb6f4b2f8fJim Grosbach int SPAdj = 0; 8263d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach 827b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbach // The instruction stream may change in the loop, so check BB->end() 828b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbach // directly. 829332553768242e82383df61d9161d1a665bfb3122Jim Grosbach for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) { 8303d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach MachineInstr *MI = I; 831332553768242e82383df61d9161d1a665bfb3122Jim Grosbach for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 8323d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach if (MI->getOperand(i).isReg()) { 833b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbach MachineOperand &MO = MI->getOperand(i); 834b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbach unsigned Reg = MO.getReg(); 83532030fe021ee614df6fdd77a2228e0e265049f3dJim Grosbach if (Reg == 0) 8369a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach continue; 837700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach if (!TargetRegisterInfo::isVirtualRegister(Reg)) 83832030fe021ee614df6fdd77a2228e0e265049f3dJim Grosbach continue; 839c52b3cced8aebbc665021ec6b8bcd0974c4ad7aeJim Grosbach 840700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach ++NumVirtualFrameRegs; 8419a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach 842e40bf5f9f40a4672cd55bfa51c64a4bb6f4b2f8fJim Grosbach // Have we already allocated a scratch register for this virtual? 843700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach if (Reg != VirtReg) { 844e40bf5f9f40a4672cd55bfa51c64a4bb6f4b2f8fJim Grosbach // When we first encounter a new virtual register, it 845e40bf5f9f40a4672cd55bfa51c64a4bb6f4b2f8fJim Grosbach // must be a definition. 846e40bf5f9f40a4672cd55bfa51c64a4bb6f4b2f8fJim Grosbach assert(MI->getOperand(i).isDef() && 847e40bf5f9f40a4672cd55bfa51c64a4bb6f4b2f8fJim Grosbach "frame index virtual missing def!"); 848332553768242e82383df61d9161d1a665bfb3122Jim Grosbach // Scavenge a new scratch register 849700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach VirtReg = Reg; 850332553768242e82383df61d9161d1a665bfb3122Jim Grosbach const TargetRegisterClass *RC = Fn.getRegInfo().getRegClass(Reg); 851700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach ScratchReg = RS->scavengeRegister(RC, I, SPAdj); 852c52b3cced8aebbc665021ec6b8bcd0974c4ad7aeJim Grosbach ++NumScavengedRegs; 8533d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach } 854c0c7c2b6061e7ca2d528bbedadb1bea0561c9158Jim Grosbach // Replace this reference to the virtual register with the 855332553768242e82383df61d9161d1a665bfb3122Jim Grosbach // scratch register. 856700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach assert (ScratchReg && "Missing scratch register!"); 857700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach MI->getOperand(i).setReg(ScratchReg); 8589a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach 8593d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach } 860332553768242e82383df61d9161d1a665bfb3122Jim Grosbach } 8610f657b156f3d0890584bedda7294932a20b2ea16Jim Grosbach RS->forward(I); 8620f657b156f3d0890584bedda7294932a20b2ea16Jim Grosbach ++I; 8633d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach } 8643d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach } 8653d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach} 866