PrologEpilogInserter.cpp revision 7271ac2c0318043688ddc8686dd23777dca62c59
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" 328a0d41e1a649c32e1f0e22c6c201a2e0d8463e30Derek Schuff#include "llvm/CodeGen/MachineModuleInfo.h" 3384bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner#include "llvm/CodeGen/MachineRegisterInfo.h" 3449dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng#include "llvm/CodeGen/RegisterScavenging.h" 350b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/InlineAsm.h" 363d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach#include "llvm/Support/CommandLine.h" 37a4f0b3a084d120cfc5b5bb06f64b222f5cb72740Chris Lattner#include "llvm/Support/Compiler.h" 383d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/Support/Debug.h" 39c0cc28301a7fa71ae895dd637058e0624f6bd399Quentin Colombet#include "llvm/Support/raw_ostream.h" 40d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetFrameLowering.h" 41d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetInstrInfo.h" 42d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetMachine.h" 43d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetRegisterInfo.h" 44c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng#include <climits> 45ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 4605d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattnerusing namespace llvm; 47d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 48378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosbychar PEI::ID = 0; 491dd8c8560d45d36a8e507cd014352f1d313f9f9eAndrew Trickchar &llvm::PrologEpilogCodeInserterID = PEI::ID; 50b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 51c0cc28301a7fa71ae895dd637058e0624f6bd399Quentin Colombetstatic cl::opt<unsigned> 52c0cc28301a7fa71ae895dd637058e0624f6bd399Quentin ColombetWarnStackSize("warn-stack-size", cl::Hidden, cl::init((unsigned)-1), 53c0cc28301a7fa71ae895dd637058e0624f6bd399Quentin Colombet cl::desc("Warn for stack size bigger than the given" 54c0cc28301a7fa71ae895dd637058e0624f6bd399Quentin Colombet " number")); 55c0cc28301a7fa71ae895dd637058e0624f6bd399Quentin Colombet 562ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_BEGIN(PEI, "prologepilog", 572ab36d350293c77fc8941ce1023e4899df7e3a82Owen Anderson "Prologue/Epilogue Insertion", false, false) 582ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) 592ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) 6025600cf50df79a6e7f8365a3ca7e940592e8ca74Andrew TrickINITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 612ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_END(PEI, "prologepilog", 621dd8c8560d45d36a8e507cd014352f1d313f9f9eAndrew Trick "Prologue/Epilogue Insertion & Frame Finalization", 631dd8c8560d45d36a8e507cd014352f1d313f9f9eAndrew Trick false, false) 64b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 65c52b3cced8aebbc665021ec6b8bcd0974c4ad7aeJim GrosbachSTATISTIC(NumScavengedRegs, "Number of frame index regs scavenged"); 66b10946a5a938a433ca4d7301b8b5ff5a8c11a7ffEvan ChengSTATISTIC(NumBytesStackSpace, 67b10946a5a938a433ca4d7301b8b5ff5a8c11a7ffEvan Cheng "Number of bytes used for stack in all functions"); 68c52b3cced8aebbc665021ec6b8bcd0974c4ad7aeJim Grosbach 69378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby/// runOnMachineFunction - Insert prolog/epilog code and replace abstract 70378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby/// frame indexes with appropriate references. 71b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby/// 72378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosbybool PEI::runOnMachineFunction(MachineFunction &Fn) { 73c5ec8a78ea898087ad361e5b755f74a76150e5fdAnton Korobeynikov const Function* F = Fn.getFunction(); 74b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo(); 7516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering *TFI = Fn.getTarget().getFrameLowering(); 7694c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov 7719273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick assert(!Fn.getRegInfo().getNumVirtRegs() && "Regalloc must assign all vregs"); 7819273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick 79378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby RS = TRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : NULL; 8065c58daa8b8985d2116216043103009815a55e77Jim Grosbach FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(Fn); 81378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 82b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling // Calculate the MaxCallFrameSize and AdjustsStack variables for the 83b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling // function's frame information. Also eliminates call frame pseudo 84b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling // instructions. 8533b350bf24be396a127c81af045468765731afc7Anton Korobeynikov calculateCallsInformation(Fn); 8633b350bf24be396a127c81af045468765731afc7Anton Korobeynikov 87378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // Allow the target machine to make some adjustments to the function 88378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // e.g. UsedPhysRegs before calculateCalleeSavedRegisters. 8994c5ae08750f314bc3cf1bf882b686244a3927d9Anton Korobeynikov TFI->processFunctionBeforeCalleeSavedScan(Fn, RS); 90378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 9133b350bf24be396a127c81af045468765731afc7Anton Korobeynikov // Scan the function for modified callee saved registers and insert spill code 9233b350bf24be396a127c81af045468765731afc7Anton Korobeynikov // for any callee saved registers that are modified. 93378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby calculateCalleeSavedRegisters(Fn); 94378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 95378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // Determine placement of CSR spill/restore code: 965b02901e91a155feca84d7383c1e569aacd1739eJim Grosbach // - With shrink wrapping, place spills and restores to tightly 97378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // enclose regions in the Machine CFG of the function where 985b02901e91a155feca84d7383c1e569aacd1739eJim Grosbach // they are used. 995b02901e91a155feca84d7383c1e569aacd1739eJim Grosbach // - Without shink wrapping (default), place all spills in the 100378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // entry block, all restores in return blocks. 101378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby placeCSRSpillsAndRestores(Fn); 102378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 103378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // Add the code to save and restore the callee saved registers 104831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling if (!F->getAttributes().hasAttribute(AttributeSet::FunctionIndex, 105831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling Attribute::Naked)) 106c5ec8a78ea898087ad361e5b755f74a76150e5fdAnton Korobeynikov insertCSRSpillsAndRestores(Fn); 107378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 108378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // Allow the target machine to make final modifications to the function 109378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // before the frame layout is finalized. 1103080d23fde4981835d8a7faf46c152441fadb11fHal Finkel TFI->processFunctionBeforeFrameFinalized(Fn, RS); 111378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 112378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // Calculate actual frame offsets for all abstract stack objects... 113378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby calculateFrameObjectOffsets(Fn); 114378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 115378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // Add prolog and epilog code to the function. This function is required 116378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // to align the stack frame as necessary for any stack variables or 117b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling // called functions. Because of this, calculateCalleeSavedRegisters() 118b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling // must be called before this function in order to set the AdjustsStack 119378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // and MaxCallFrameSize variables. 120831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling if (!F->getAttributes().hasAttribute(AttributeSet::FunctionIndex, 121831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling Attribute::Naked)) 122c5ec8a78ea898087ad361e5b755f74a76150e5fdAnton Korobeynikov insertPrologEpilogCode(Fn); 123378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 124378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // Replace all MO_FrameIndex operands with physical register references 125378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // and actual offsets. 126378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // 127378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby replaceFrameIndices(Fn); 128b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 1293d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach // If register scavenging is needed, as we've enabled doing it as a 1303d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach // post-pass, scavenge the virtual registers that frame index elimiation 1313d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach // inserted. 1323d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach if (TRI->requiresRegisterScavenging(Fn) && FrameIndexVirtualScavenging) 1333d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach scavengeFrameVirtualRegs(Fn); 1343d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach 13519273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick // Clear any vregs created by virtual scavenging. 13619273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick Fn.getRegInfo().clearVirtRegs(); 13719273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick 138c0cc28301a7fa71ae895dd637058e0624f6bd399Quentin Colombet // Warn on stack size when we exceeds the given limit. 139c0cc28301a7fa71ae895dd637058e0624f6bd399Quentin Colombet MachineFrameInfo *MFI = Fn.getFrameInfo(); 140c0cc28301a7fa71ae895dd637058e0624f6bd399Quentin Colombet if (WarnStackSize.getNumOccurrences() > 0 && 141c0cc28301a7fa71ae895dd637058e0624f6bd399Quentin Colombet WarnStackSize < MFI->getStackSize()) 142c0cc28301a7fa71ae895dd637058e0624f6bd399Quentin Colombet errs() << "warning: Stack size limit exceeded (" << MFI->getStackSize() 143c0cc28301a7fa71ae895dd637058e0624f6bd399Quentin Colombet << ") in " << Fn.getName() << ".\n"; 144c0cc28301a7fa71ae895dd637058e0624f6bd399Quentin Colombet 145378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby delete RS; 146378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby clearAllSets(); 147b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby return true; 148ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby} 149ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 150b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling/// calculateCallsInformation - Calculate the MaxCallFrameSize and AdjustsStack 15133b350bf24be396a127c81af045468765731afc7Anton Korobeynikov/// variables for the function's frame information and eliminate call frame 15233b350bf24be396a127c81af045468765731afc7Anton Korobeynikov/// pseudo instructions. 15333b350bf24be396a127c81af045468765731afc7Anton Korobeynikovvoid PEI::calculateCallsInformation(MachineFunction &Fn) { 154d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); 15516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering *TFI = Fn.getTarget().getFrameLowering(); 1569e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman MachineFrameInfo *MFI = Fn.getFrameInfo(); 15758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 15833b350bf24be396a127c81af045468765731afc7Anton Korobeynikov unsigned MaxCallFrameSize = 0; 159b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling bool AdjustsStack = MFI->adjustsStack(); 16058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 16158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Get the function call frame set-up and tear-down instruction opcode 162d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng int FrameSetupOpcode = TII.getCallFrameSetupOpcode(); 163d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng int FrameDestroyOpcode = TII.getCallFrameDestroyOpcode(); 16458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 16533b350bf24be396a127c81af045468765731afc7Anton Korobeynikov // Early exit for targets which have no call frame setup/destroy pseudo 16633b350bf24be396a127c81af045468765731afc7Anton Korobeynikov // instructions. 16733b350bf24be396a127c81af045468765731afc7Anton Korobeynikov if (FrameSetupOpcode == -1 && FrameDestroyOpcode == -1) 16858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner return; 16958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 1705c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng std::vector<MachineBasicBlock::iterator> FrameSDOps; 17158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) 1725c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) 173c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos if (I->getOpcode() == FrameSetupOpcode || 174d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner I->getOpcode() == FrameDestroyOpcode) { 1752a82ef317c39ac436f80854c7ddbb06bfddeada1Chris Lattner assert(I->getNumOperands() >= 1 && "Call Frame Setup/Destroy Pseudo" 176d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner " instructions should have a single immediate argument!"); 1779e3304900ff69c4920fea7369c9c36916c4a6a6aChris Lattner unsigned Size = I->getOperand(0).getImm(); 178d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner if (Size > MaxCallFrameSize) MaxCallFrameSize = Size; 179b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling AdjustsStack = true; 1805c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng FrameSDOps.push_back(I); 181518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner } else if (I->isInlineAsm()) { 182f1e309eb4862459a76445942ba4dafc433b6f317Dale Johannesen // Some inline asm's need a stack frame, as indicated by operand 1. 183c36b7069b42bece963b7e6adf020353ce990ef76Evan Cheng unsigned ExtraInfo = I->getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 184c36b7069b42bece963b7e6adf020353ce990ef76Evan Cheng if (ExtraInfo & InlineAsm::Extra_IsAlignStack) 185f1e309eb4862459a76445942ba4dafc433b6f317Dale Johannesen AdjustsStack = true; 18658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 18758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 188b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling MFI->setAdjustsStack(AdjustsStack); 1899e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman MFI->setMaxCallFrameSize(MaxCallFrameSize); 1908e3347332120956538a6d882b02719e34b57f0cdEvan Cheng 191058a024eb7265239d527680b0a448cdb48102a46Bill Wendling for (std::vector<MachineBasicBlock::iterator>::iterator 192058a024eb7265239d527680b0a448cdb48102a46Bill Wendling i = FrameSDOps.begin(), e = FrameSDOps.end(); i != e; ++i) { 193058a024eb7265239d527680b0a448cdb48102a46Bill Wendling MachineBasicBlock::iterator I = *i; 194058a024eb7265239d527680b0a448cdb48102a46Bill Wendling 195058a024eb7265239d527680b0a448cdb48102a46Bill Wendling // If call frames are not being included as part of the stack frame, and 1964642ad3af1cf508ac320b9afd25b065f08b36574Jim Grosbach // the target doesn't indicate otherwise, remove the call frame pseudos 1974642ad3af1cf508ac320b9afd25b065f08b36574Jim Grosbach // here. The sub/add sp instruction pairs are still inserted, but we don't 1984642ad3af1cf508ac320b9afd25b065f08b36574Jim Grosbach // need to track the SP adjustment for frame index elimination. 199d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (TFI->canSimplifyCallFramePseudos(Fn)) 200700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky TFI->eliminateCallFramePseudoInstr(Fn, *I->getParent(), I); 2015c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng } 20233b350bf24be396a127c81af045468765731afc7Anton Korobeynikov} 20333b350bf24be396a127c81af045468765731afc7Anton Korobeynikov 20433b350bf24be396a127c81af045468765731afc7Anton Korobeynikov 20533b350bf24be396a127c81af045468765731afc7Anton Korobeynikov/// calculateCalleeSavedRegisters - Scan the function for modified callee saved 20633b350bf24be396a127c81af045468765731afc7Anton Korobeynikov/// registers. 207831737d329a727f53a1fb0572f7b7a8127208881Bill Wendlingvoid PEI::calculateCalleeSavedRegisters(MachineFunction &F) { 208831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling const TargetRegisterInfo *RegInfo = F.getTarget().getRegisterInfo(); 209831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling const TargetFrameLowering *TFI = F.getTarget().getFrameLowering(); 210831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling MachineFrameInfo *MFI = F.getFrameInfo(); 21133b350bf24be396a127c81af045468765731afc7Anton Korobeynikov 21233b350bf24be396a127c81af045468765731afc7Anton Korobeynikov // Get the callee saved register list... 213831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling const uint16_t *CSRegs = RegInfo->getCalleeSavedRegs(&F); 21433b350bf24be396a127c81af045468765731afc7Anton Korobeynikov 21533b350bf24be396a127c81af045468765731afc7Anton Korobeynikov // These are used to keep track the callee-save area. Initialize them. 21633b350bf24be396a127c81af045468765731afc7Anton Korobeynikov MinCSFrameIndex = INT_MAX; 21733b350bf24be396a127c81af045468765731afc7Anton Korobeynikov MaxCSFrameIndex = 0; 21833b350bf24be396a127c81af045468765731afc7Anton Korobeynikov 21933b350bf24be396a127c81af045468765731afc7Anton Korobeynikov // Early exit for targets which have no callee saved registers. 22033b350bf24be396a127c81af045468765731afc7Anton Korobeynikov if (CSRegs == 0 || CSRegs[0] == 0) 22133b350bf24be396a127c81af045468765731afc7Anton Korobeynikov return; 22258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 2238c5358c93675b009ba2d57c3a5980f6bc58ba536Dale Johannesen // In Naked functions we aren't going to save any registers. 224831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling if (F.getFunction()->getAttributes().hasAttribute(AttributeSet::FunctionIndex, 225831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling Attribute::Naked)) 2268c5358c93675b009ba2d57c3a5980f6bc58ba536Dale Johannesen return; 2278c5358c93675b009ba2d57c3a5980f6bc58ba536Dale Johannesen 22808ede262a744f99429658fadb43662441bdcb42dJim Laskey std::vector<CalleeSavedInfo> CSI; 22958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner for (unsigned i = 0; CSRegs[i]; ++i) { 23058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner unsigned Reg = CSRegs[i]; 2318a0d41e1a649c32e1f0e22c6c201a2e0d8463e30Derek Schuff // Functions which call __builtin_unwind_init get all their registers saved. 2328a0d41e1a649c32e1f0e22c6c201a2e0d8463e30Derek Schuff if (F.getRegInfo().isPhysRegUsed(Reg) || F.getMMI().callsUnwindInit()) { 233058a024eb7265239d527680b0a448cdb48102a46Bill Wendling // If the reg is modified, save it! 23442d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola CSI.push_back(CalleeSavedInfo(Reg)); 23573ff5120eb8b8c0ccbfed8a17f1024c67a75f319Alkis Evlogimenos } 23658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 23758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 238f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey if (CSI.empty()) 239c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng return; // Early exit if no callee saved registers are modified! 24058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 241c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner unsigned NumFixedSpillSlots; 24216c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering::SpillSlot *FixedSpillSlots = 243ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng TFI->getCalleeSavedSpillSlots(NumFixedSpillSlots); 244c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 24558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Now that we know which registers need to be saved and restored, allocate 24658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // stack slots for them. 247058a024eb7265239d527680b0a448cdb48102a46Bill Wendling for (std::vector<CalleeSavedInfo>::iterator 248058a024eb7265239d527680b0a448cdb48102a46Bill Wendling I = CSI.begin(), E = CSI.end(); I != E; ++I) { 249058a024eb7265239d527680b0a448cdb48102a46Bill Wendling unsigned Reg = I->getReg(); 25042d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola const TargetRegisterClass *RC = RegInfo->getMinimalPhysRegClass(Reg); 251c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 252910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng int FrameIdx; 253831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling if (RegInfo->hasReservedSpillSlot(F, Reg, FrameIdx)) { 254910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng I->setFrameIdx(FrameIdx); 255910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng continue; 256910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng } 257910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng 258c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // Check to see if this physreg must be spilled to a particular stack slot 259c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // on this target. 26016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering::SpillSlot *FixedSlot = FixedSpillSlots; 261c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner while (FixedSlot != FixedSpillSlots+NumFixedSpillSlots && 2628ff95de83cbe85d939535d2f4fb5f9b2b721081aTilmann Scheller FixedSlot->Reg != Reg) 263c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner ++FixedSlot; 264c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 265058a024eb7265239d527680b0a448cdb48102a46Bill Wendling if (FixedSlot == FixedSpillSlots + NumFixedSpillSlots) { 266c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // Nope, just spill it anywhere convenient. 2675feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng unsigned Align = RC->getAlignment(); 2685feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng unsigned StackAlign = TFI->getStackAlignment(); 269058a024eb7265239d527680b0a448cdb48102a46Bill Wendling 270058a024eb7265239d527680b0a448cdb48102a46Bill Wendling // We may not be able to satisfy the desired alignment specification of 271058a024eb7265239d527680b0a448cdb48102a46Bill Wendling // the TargetRegisterClass if the stack alignment is smaller. Use the 272058a024eb7265239d527680b0a448cdb48102a46Bill Wendling // min. 2735feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng Align = std::min(Align, StackAlign); 2749e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman FrameIdx = MFI->CreateStackObject(RC->getSize(), Align, true); 275c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng if ((unsigned)FrameIdx < MinCSFrameIndex) MinCSFrameIndex = FrameIdx; 276c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng if ((unsigned)FrameIdx > MaxCSFrameIndex) MaxCSFrameIndex = FrameIdx; 277c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner } else { 278c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // Spill it to the stack where we must. 279ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng FrameIdx = MFI->CreateFixedObject(RC->getSize(), FixedSlot->Offset, true); 280c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner } 281058a024eb7265239d527680b0a448cdb48102a46Bill Wendling 282058a024eb7265239d527680b0a448cdb48102a46Bill Wendling I->setFrameIdx(FrameIdx); 28358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 28408ede262a744f99429658fadb43662441bdcb42dJim Laskey 2859e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman MFI->setCalleeSavedInfo(CSI); 286c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner} 287c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 288ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby/// insertCSRSpillsAndRestores - Insert spill and restore code for 289ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby/// callee saved registers used in the function, handling shrink wrapping. 290c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner/// 291ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosbyvoid PEI::insertCSRSpillsAndRestores(MachineFunction &Fn) { 292f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey // Get callee saved register information. 2939e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman MachineFrameInfo *MFI = Fn.getFrameInfo(); 2949e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 295ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 2969e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman MFI->setCalleeSavedInfoValid(true); 297d62c9a697b53f9e754926a89126fd121220ed09bJakob Stoklund Olesen 298c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Early exit if no callee saved registers are modified! 299f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey if (CSI.empty()) 300edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman return; 301c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 302f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); 30316c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering *TFI = Fn.getTarget().getFrameLowering(); 304746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo(); 305ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby MachineBasicBlock::iterator I; 30600dff8dda29b5a249cd99405ce26e84cef13ba53Evan Cheng 30706a23ea8083657270e86a178abf050246caac0b5Chad Rosier if (!ShrinkWrapThisFunction) { 308b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // Spill using target interface. 309b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby I = EntryBlock->begin(); 310cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov if (!TFI->spillCalleeSavedRegisters(*EntryBlock, I, CSI, TRI)) { 311b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 312ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // Add the callee-saved register as live-in. 313ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // It's killed at the spill. 314b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby EntryBlock->addLiveIn(CSI[i].getReg()); 315ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 316ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // Insert the spill to the stack frame. 31742d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola unsigned Reg = CSI[i].getReg(); 31842d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 31942d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola TII.storeRegToStackSlot(*EntryBlock, I, Reg, true, 32042d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola CSI[i].getFrameIdx(), RC, TRI); 321ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby } 322ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng } 323ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 324b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // Restore using target interface. 325b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby for (unsigned ri = 0, re = ReturnBlocks.size(); ri != re; ++ri) { 326b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby MachineBasicBlock* MBB = ReturnBlocks[ri]; 327c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos I = MBB->end(); --I; 32858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 329f7c094000f4baf094b1d60ba68a5b4e0193c502aBill Wendling // Skip over all terminator instructions, which are part of the return 3304fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner // sequence. 3314fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner MachineBasicBlock::iterator I2 = I; 3325a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng while (I2 != MBB->begin() && (--I2)->isTerminator()) 3334fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner I = I2; 3344fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner 335dfd58709cc78e841ef4a50ba75d940473031617eChris Lattner bool AtStart = I == MBB->begin(); 336ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner MachineBasicBlock::iterator BeforeI = I; 337ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner if (!AtStart) 338ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner --BeforeI; 339ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 340ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // Restore all registers immediately before the return and any 3417a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // terminators that precede it. 342cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov if (!TFI->restoreCalleeSavedRegisters(*MBB, I, CSI, TRI)) { 343ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 34442d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola unsigned Reg = CSI[i].getReg(); 34542d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 34642d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola TII.loadRegFromStackSlot(*MBB, I, Reg, 347ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby CSI[i].getFrameIdx(), 34842d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola RC, TRI); 349ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng assert(I != MBB->begin() && 350ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng "loadRegFromStackSlot didn't insert any code!"); 351ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // Insert in reverse order. loadRegFromStackSlot can insert 352ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // multiple instructions. 353ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng if (AtStart) 354ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng I = MBB->begin(); 355ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng else { 356ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng I = BeforeI; 357ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng ++I; 358ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng } 359ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner } 36058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 361b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } 362b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby return; 363b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } 364ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 365b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // Insert spills. 366b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby std::vector<CalleeSavedInfo> blockCSI; 367b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby for (CSRegBlockMap::iterator BI = CSRSave.begin(), 368b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby BE = CSRSave.end(); BI != BE; ++BI) { 369b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby MachineBasicBlock* MBB = BI->first; 370b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby CSRegSet save = BI->second; 371ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 372b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby if (save.empty()) 373b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby continue; 374ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 375b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby blockCSI.clear(); 376b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby for (CSRegSet::iterator RI = save.begin(), 377b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby RE = save.end(); RI != RE; ++RI) { 378b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby blockCSI.push_back(CSI[*RI]); 379b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } 380b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby assert(blockCSI.size() > 0 && 381b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby "Could not collect callee saved register info"); 382b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 383b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby I = MBB->begin(); 384b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 385b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // When shrink wrapping, use stack slot stores/loads. 386b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby for (unsigned i = 0, e = blockCSI.size(); i != e; ++i) { 387b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // Add the callee-saved register as live-in. 388b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // It's killed at the spill. 389b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby MBB->addLiveIn(blockCSI[i].getReg()); 390b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 391b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // Insert the spill to the stack frame. 39242d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola unsigned Reg = blockCSI[i].getReg(); 39342d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 39442d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola TII.storeRegToStackSlot(*MBB, I, Reg, 395b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby true, 396b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby blockCSI[i].getFrameIdx(), 39742d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola RC, TRI); 398b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } 399b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } 400b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 401b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby for (CSRegBlockMap::iterator BI = CSRRestore.begin(), 402b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby BE = CSRRestore.end(); BI != BE; ++BI) { 403b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby MachineBasicBlock* MBB = BI->first; 404b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby CSRegSet restore = BI->second; 405b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 406b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby if (restore.empty()) 407b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby continue; 408b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 409b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby blockCSI.clear(); 410b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby for (CSRegSet::iterator RI = restore.begin(), 411b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby RE = restore.end(); RI != RE; ++RI) { 412b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby blockCSI.push_back(CSI[*RI]); 413b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } 414b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby assert(blockCSI.size() > 0 && 415b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby "Could not find callee saved register info"); 416b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 417b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // If MBB is empty and needs restores, insert at the _beginning_. 418b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby if (MBB->empty()) { 419b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby I = MBB->begin(); 420b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } else { 421b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby I = MBB->end(); 422b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby --I; 423b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 424b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // Skip over all terminator instructions, which are part of the 425b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // return sequence. 4265a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng if (! I->isTerminator()) { 427b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby ++I; 428ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby } else { 429b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby MachineBasicBlock::iterator I2 = I; 4305a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng while (I2 != MBB->begin() && (--I2)->isTerminator()) 431b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby I = I2; 432ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby } 433b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } 434ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 435b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby bool AtStart = I == MBB->begin(); 436b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby MachineBasicBlock::iterator BeforeI = I; 437b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby if (!AtStart) 438b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby --BeforeI; 439b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 440b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // Restore all registers immediately before the return and any 4417a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // terminators that precede it. 442b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby for (unsigned i = 0, e = blockCSI.size(); i != e; ++i) { 44342d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola unsigned Reg = blockCSI[i].getReg(); 44442d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 44542d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola TII.loadRegFromStackSlot(*MBB, I, Reg, 446b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby blockCSI[i].getFrameIdx(), 44742d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola RC, TRI); 448b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby assert(I != MBB->begin() && 449b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby "loadRegFromStackSlot didn't insert any code!"); 450b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // Insert in reverse order. loadRegFromStackSlot can insert 451b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // multiple instructions. 452b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby if (AtStart) 453b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby I = MBB->begin(); 454b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby else { 455b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby I = BeforeI; 456b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby ++I; 457ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby } 45858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 459ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby } 46058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner} 46158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 462cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling/// AdjustStackOffset - Helper function used to adjust the stack frame offset. 463cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendlingstatic inline void 4649e9aa44d1a33fb845268ba07b726a31f26195690Dan GohmanAdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx, 465cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling bool StackGrowsDown, int64_t &Offset, 466cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling unsigned &MaxAlign) { 46794188d4e67cf1c570ad87dbabf198931033d628eBob Wilson // If the stack grows down, add the object size to find the lowest address. 468cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling if (StackGrowsDown) 4699e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman Offset += MFI->getObjectSize(FrameIdx); 470cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling 4719e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman unsigned Align = MFI->getObjectAlignment(FrameIdx); 472cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling 473cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling // If the alignment of this object is greater than that of the stack, then 474cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling // increase the stack alignment to match. 475cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling MaxAlign = std::max(MaxAlign, Align); 476cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling 477cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling // Adjust to alignment boundary. 478cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling Offset = (Offset + Align - 1) / Align * Align; 479cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling 480cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling if (StackGrowsDown) { 4813d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << -Offset << "]\n"); 4829e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman MFI->setObjectOffset(FrameIdx, -Offset); // Set the computed offset 483cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling } else { 4843d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << Offset << "]\n"); 4859e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman MFI->setObjectOffset(FrameIdx, Offset); 4869e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman Offset += MFI->getObjectSize(FrameIdx); 487cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling } 488cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling} 48958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 49058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the 49192b9fcea7b3180ed18f379212d14bd5cea7a1954Chris Lattner/// abstract stack objects. 49258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// 49358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattnervoid PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { 49416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering &TFI = *Fn.getTarget().getFrameLowering(); 495edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 49658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner bool StackGrowsDown = 49716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown; 498edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 49958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Loop over all of the stack objects, assigning sequential addresses... 5009e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman MachineFrameInfo *MFI = Fn.getFrameInfo(); 50158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 50205d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner // Start at the beginning of the local area. 503577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // The Offset is the distance from the stack top in the direction 504c0d6012b31afa2220306afa27db1b02e18427776Dan Gohman // of stack growth -- so it's always nonnegative. 505c34666ee1871d47dfa4865c7138902dd1b770101Bob Wilson int LocalAreaOffset = TFI.getOffsetOfLocalArea(); 506577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner if (StackGrowsDown) 507c34666ee1871d47dfa4865c7138902dd1b770101Bob Wilson LocalAreaOffset = -LocalAreaOffset; 508c34666ee1871d47dfa4865c7138902dd1b770101Bob Wilson assert(LocalAreaOffset >= 0 509577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner && "Local area offset should be in direction of stack growth"); 510c34666ee1871d47dfa4865c7138902dd1b770101Bob Wilson int64_t Offset = LocalAreaOffset; 511577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner 512577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // If there are fixed sized objects that are preallocated in the local area, 513577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // non-fixed objects can't be allocated right at the start of local area. 514ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // We currently don't support filling in holes in between fixed sized 515ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // objects, so we adjust 'Offset' to point to the end of last fixed sized 51605d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner // preallocated object. 5179e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman for (int i = MFI->getObjectIndexBegin(); i != 0; ++i) { 518a401b1e1c5eb9563617db8a2477b4c5f8b239521Chris Lattner int64_t FixedOff; 519577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner if (StackGrowsDown) { 520577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // The maximum distance from the stack pointer is at lower address of 521577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // the object -- which is given by offset. For down growing stack 522577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // the offset is negative, so we negate the offset to get the distance. 5239e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman FixedOff = -MFI->getObjectOffset(i); 524577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner } else { 525edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman // The maximum distance from the start pointer is at the upper 526577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // address of the object. 5279e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman FixedOff = MFI->getObjectOffset(i) + MFI->getObjectSize(i); 528edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman } 529edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman if (FixedOff > Offset) Offset = FixedOff; 53005d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner } 53105d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner 532c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // First assign frame offsets to stack objects that are used to spill 533ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng // callee saved registers. 534c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng if (StackGrowsDown) { 5355c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng for (unsigned i = MinCSFrameIndex; i <= MaxCSFrameIndex; ++i) { 536b4c14aaa50b58ac723d0ed179695e1cd7296572aEric Christopher // If the stack grows down, we need to add the size to find the lowest 537c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // address of the object. 5389e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman Offset += MFI->getObjectSize(i); 539c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 5409e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman unsigned Align = MFI->getObjectAlignment(i); 541c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Adjust to alignment boundary 542c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng Offset = (Offset+Align-1)/Align*Align; 543c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 5449e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman MFI->setObjectOffset(i, -Offset); // Set the computed offset 545c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng } 546c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng } else { 547a8c63f0fc9feb48f17d702a907f065959c41e337Bruno Cardoso Lopes int MaxCSFI = MaxCSFrameIndex, MinCSFI = MinCSFrameIndex; 548a8c63f0fc9feb48f17d702a907f065959c41e337Bruno Cardoso Lopes for (int i = MaxCSFI; i >= MinCSFI ; --i) { 5499e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman unsigned Align = MFI->getObjectAlignment(i); 550c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Adjust to alignment boundary 551c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng Offset = (Offset+Align-1)/Align*Align; 552c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 5539e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman MFI->setObjectOffset(i, Offset); 5549e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman Offset += MFI->getObjectSize(i); 555c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng } 556c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng } 557c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 5589e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman unsigned MaxAlign = MFI->getMaxAlignment(); 5597545f49a5edfe19612d03e683d8b955c03018056Evan Cheng 56087f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // Make sure the special register scavenging spill slot is closest to the 5617271ac2c0318043688ddc8686dd23777dca62c59Richard Sandiford // incoming stack pointer if a frame pointer is required and is closer 5627271ac2c0318043688ddc8686dd23777dca62c59Richard Sandiford // to the incoming rather than the final stack pointer. 5636f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); 5647271ac2c0318043688ddc8686dd23777dca62c59Richard Sandiford bool EarlyScavengingSlots = (TFI.hasFP(Fn) && 5657271ac2c0318043688ddc8686dd23777dca62c59Richard Sandiford TFI.isFPCloseToIncomingSP() && 5667271ac2c0318043688ddc8686dd23777dca62c59Richard Sandiford RegInfo->useFPForScavengingIndex(Fn) && 5677271ac2c0318043688ddc8686dd23777dca62c59Richard Sandiford !RegInfo->needsStackRealignment(Fn)); 5687271ac2c0318043688ddc8686dd23777dca62c59Richard Sandiford if (RS && EarlyScavengingSlots) { 569dc3beb90178fc316f63790812b22201884eaa017Hal Finkel SmallVector<int, 2> SFIs; 570dc3beb90178fc316f63790812b22201884eaa017Hal Finkel RS->getScavengingFrameIndices(SFIs); 571f22fd3f7b557a967b1edc1fa9ae770006a39e97cCraig Topper for (SmallVectorImpl<int>::iterator I = SFIs.begin(), 572f22fd3f7b557a967b1edc1fa9ae770006a39e97cCraig Topper IE = SFIs.end(); I != IE; ++I) 573dc3beb90178fc316f63790812b22201884eaa017Hal Finkel AdjustStackOffset(MFI, *I, StackGrowsDown, Offset, MaxAlign); 57487f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng } 57587f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 5764861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach // FIXME: Once this is working, then enable flag will change to a target 5774861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach // check for whether the frame is large enough to want to use virtual 5784861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach // frame index registers. Functions which don't want/need this optimization 5794861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach // will continue to use the existing code path. 580a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach if (MFI->getUseLocalStackAllocationBlock()) { 5814861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach unsigned Align = MFI->getLocalFrameMaxAlign(); 5824861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach 5834861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach // Adjust to alignment boundary. 5844861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach Offset = (Offset + Align - 1) / Align * Align; 5854861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach 586fecdea0bf77599038eb368db3bc6a38a14900308Jim Grosbach DEBUG(dbgs() << "Local frame base offset: " << Offset << "\n"); 587fecdea0bf77599038eb368db3bc6a38a14900308Jim Grosbach 5883d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // Resolve offsets for objects in the local block. 5893d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach for (unsigned i = 0, e = MFI->getLocalFrameObjectCount(); i != e; ++i) { 5903d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach std::pair<int, int64_t> Entry = MFI->getLocalFrameObjectMap(i); 59167ff81a08319f916571cea90ed92e17015c8584fJim Grosbach int64_t FIOffset = (StackGrowsDown ? -Offset : Offset) + Entry.second; 59267ff81a08319f916571cea90ed92e17015c8584fJim Grosbach DEBUG(dbgs() << "alloc FI(" << Entry.first << ") at SP[" << 59367ff81a08319f916571cea90ed92e17015c8584fJim Grosbach FIOffset << "]\n"); 59467ff81a08319f916571cea90ed92e17015c8584fJim Grosbach MFI->setObjectOffset(Entry.first, FIOffset); 5953d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach } 59667ff81a08319f916571cea90ed92e17015c8584fJim Grosbach // Allocate the local block 59767ff81a08319f916571cea90ed92e17015c8584fJim Grosbach Offset += MFI->getLocalFrameSize(); 59867ff81a08319f916571cea90ed92e17015c8584fJim Grosbach 59967ff81a08319f916571cea90ed92e17015c8584fJim Grosbach MaxAlign = std::max(Align, MaxAlign); 6003d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach } 6013d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 602b2a4298ce41e7ef80cd75a3c1dfa6433f0759a1aBill Wendling // Make sure that the stack protector comes before the local variables on the 603b2a4298ce41e7ef80cd75a3c1dfa6433f0759a1aBill Wendling // stack. 604dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling SmallSet<int, 16> LargeStackObjs; 605dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling if (MFI->getStackProtectorIndex() >= 0) { 6069e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman AdjustStackOffset(MFI, MFI->getStackProtectorIndex(), StackGrowsDown, 607cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling Offset, MaxAlign); 608b2a4298ce41e7ef80cd75a3c1dfa6433f0759a1aBill Wendling 609dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling // Assign large stack objects first. 610dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) { 611a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach if (MFI->isObjectPreAllocated(i) && 612a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach MFI->getUseLocalStackAllocationBlock()) 6133d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach continue; 614dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex) 615dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling continue; 616dc3beb90178fc316f63790812b22201884eaa017Hal Finkel if (RS && RS->isScavengingFrameIndex((int)i)) 617dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling continue; 618dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling if (MFI->isDeadObjectIndex(i)) 619dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling continue; 620dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling if (MFI->getStackProtectorIndex() == (int)i) 621dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling continue; 622dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling if (!MFI->MayNeedStackProtector(i)) 623dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling continue; 624dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling 625dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign); 626dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling LargeStackObjs.insert(i); 627dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling } 628dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling } 629dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling 630c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Then assign frame offsets to stack objects that are not used to spill 631ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng // callee saved registers. 6329e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) { 633a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach if (MFI->isObjectPreAllocated(i) && 634a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach MFI->getUseLocalStackAllocationBlock()) 6353d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach continue; 636c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex) 637c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng continue; 638dc3beb90178fc316f63790812b22201884eaa017Hal Finkel if (RS && RS->isScavengingFrameIndex((int)i)) 63987f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng continue; 6409e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman if (MFI->isDeadObjectIndex(i)) 641d36531249a9a9500e516148e7e72d4c0a7a4d0eeEvan Cheng continue; 6429e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman if (MFI->getStackProtectorIndex() == (int)i) 64344cf38c01ff610139d2e8dbbdc4e6123a3debcddBill Wendling continue; 644dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling if (LargeStackObjs.count(i)) 645dfc2c51d12fd53822279b6e564cdd5cef5c00b46Bill Wendling continue; 646c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 6479e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign); 64858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 64958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 65087f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // Make sure the special register scavenging spill slot is closest to the 65187f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // stack pointer. 6527271ac2c0318043688ddc8686dd23777dca62c59Richard Sandiford if (RS && !EarlyScavengingSlots) { 653dc3beb90178fc316f63790812b22201884eaa017Hal Finkel SmallVector<int, 2> SFIs; 654dc3beb90178fc316f63790812b22201884eaa017Hal Finkel RS->getScavengingFrameIndices(SFIs); 655f22fd3f7b557a967b1edc1fa9ae770006a39e97cCraig Topper for (SmallVectorImpl<int>::iterator I = SFIs.begin(), 656f22fd3f7b557a967b1edc1fa9ae770006a39e97cCraig Topper IE = SFIs.end(); I != IE; ++I) 657dc3beb90178fc316f63790812b22201884eaa017Hal Finkel AdjustStackOffset(MFI, *I, StackGrowsDown, Offset, MaxAlign); 65887f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng } 65987f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 66033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (!TFI.targetHandlesStackFrameRounding()) { 6615c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng // If we have reserved argument space for call sites in the function 6625c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng // immediately on entry to the current function, count it as part of the 6635c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng // overall stack size. 664d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (MFI->adjustsStack() && TFI.hasReservedCallFrame(Fn)) 6659e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman Offset += MFI->getMaxCallFrameSize(); 666367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng 6670035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson // Round up the size to a multiple of the alignment. If the function has 6680035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson // any calls or alloca's, align to the target's StackAlignment value to 6690035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson // ensure that the callee's frame or the alloca data is suitably aligned; 6700035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson // otherwise, for leaf functions, align to the TransientStackAlignment 6710035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson // value. 6720035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson unsigned StackAlign; 673b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling if (MFI->adjustsStack() || MFI->hasVarSizedObjects() || 6749e9aa44d1a33fb845268ba07b726a31f26195690Dan Gohman (RegInfo->needsStackRealignment(Fn) && MFI->getObjectIndexEnd() != 0)) 6750035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson StackAlign = TFI.getStackAlignment(); 6760035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson else 6770035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson StackAlign = TFI.getTransientStackAlignment(); 678b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling 679b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling // If the frame pointer is eliminated, all frame offsets will be relative to 680b92187a4103dca24c3767c380f63593d1f6161a7Bill Wendling // SP not FP. Align to MaxAlign so this works. 6810035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson StackAlign = std::max(StackAlign, MaxAlign); 6820035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson unsigned AlignMask = StackAlign - 1; 683ea84c5ee952c62dd0c703c9852d7a60715e4a435Chris Lattner Offset = (Offset + AlignMask) & ~uint64_t(AlignMask); 684367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng } 685367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng 686367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng // Update frame info to pretend that this is part of the stack... 687c219d191aadb4f9532bcaea5c5e66f66912656caJakob Stoklund Olesen int64_t StackSize = Offset - LocalAreaOffset; 688c219d191aadb4f9532bcaea5c5e66f66912656caJakob Stoklund Olesen MFI->setStackSize(StackSize); 689c219d191aadb4f9532bcaea5c5e66f66912656caJakob Stoklund Olesen NumBytesStackSpace += StackSize; 6904ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner} 6914ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner 692c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng/// insertPrologEpilogCode - Scan the function for modified callee saved 693c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng/// registers, insert spill code for these callee saved registers, then add 6944ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner/// prolog and epilog code to the function. 6954ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner/// 6964ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattnervoid PEI::insertPrologEpilogCode(MachineFunction &Fn) { 69716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering &TFI = *Fn.getTarget().getFrameLowering(); 698874384e20f618d6ac932628db64e048757213fcdAnton Korobeynikov 6994ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner // Add prologue to the function... 70033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TFI.emitPrologue(Fn); 7014ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner 7024ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner // Add epilogue to restore the callee-save registers in each exiting block 7034ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) { 7044ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner // If last instruction is a return instruction, add an epilogue 7055a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng if (!I->empty() && I->back().isReturn()) 70633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TFI.emitEpilogue(Fn, *I); 7074ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner } 70876927d758657b3a511c73467ec5a7288795c1513Rafael Espindola 709e81abfd30b7c81735e9f3d79006c2653690aa592Rafael Espindola // Emit additional code that is required to support segmented stacks, if 710e81abfd30b7c81735e9f3d79006c2653690aa592Rafael Espindola // we've been asked for it. This, when linked with a runtime with support 711e81abfd30b7c81735e9f3d79006c2653690aa592Rafael Espindola // for segmented stacks (libgcc is one), will result in allocating stack 712e81abfd30b7c81735e9f3d79006c2653690aa592Rafael Espindola // space in small chunks instead of one large contiguous block. 7138a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky if (Fn.getTarget().Options.EnableSegmentedStacks) 71476927d758657b3a511c73467ec5a7288795c1513Rafael Espindola TFI.adjustForSegmentedStacks(Fn); 71598fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer 71698fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // Emit additional code that is required to explicitly handle the stack in 71798fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // HiPE native code (if needed) when loaded in the Erlang/OTP runtime. The 71898fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // approach is rather similar to that of Segmented Stacks, but it uses a 71998fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // different conditional check and another BIF for allocating more stack 72098fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer // space. 72198fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer if (Fn.getFunction()->getCallingConv() == CallingConv::HiPE) 72298fbe27ac8f0766ea94b89b8c03418131b72bea4Benjamin Kramer TFI.adjustForHiPEPrologue(Fn); 72358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner} 72458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 72558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// replaceFrameIndices - Replace all MO_FrameIndex operands with physical 72658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// register references and actual offsets. 72758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// 72858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattnervoid PEI::replaceFrameIndices(MachineFunction &Fn) { 72958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner if (!Fn.getFrameInfo()->hasStackObjects()) return; // Nothing to do? 73058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 73158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner const TargetMachine &TM = Fn.getTarget(); 73258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner assert(TM.getRegisterInfo() && "TM::getRegisterInfo() must be implemented!"); 733d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); 7346f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman const TargetRegisterInfo &TRI = *TM.getRegisterInfo(); 73516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering *TFI = TM.getFrameLowering(); 7368e3347332120956538a6d882b02719e34b57f0cdEvan Cheng bool StackGrowsDown = 73716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov TFI->getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown; 738d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng int FrameSetupOpcode = TII.getCallFrameSetupOpcode(); 739d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng int FrameDestroyOpcode = TII.getCallFrameDestroyOpcode(); 74058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 741ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby for (MachineFunction::iterator BB = Fn.begin(), 742ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby E = Fn.end(); BB != E; ++BB) { 7436627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach#ifndef NDEBUG 7446627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach int SPAdjCount = 0; // frame setup / destroy count. 7456627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach#endif 7468e3347332120956538a6d882b02719e34b57f0cdEvan Cheng int SPAdj = 0; // SP offset due to call frame setup / destroy. 7473d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach if (RS && !FrameIndexVirtualScavenging) RS->enterBasicBlock(BB); 748ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 7490ebe9c132c6b9c74b334f0c7503e702b499575d5Chris Lattner for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) { 750405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 751405abffd5eb1ad1841491e51943b598c935f309bBill Wendling if (I->getOpcode() == FrameSetupOpcode || 752405abffd5eb1ad1841491e51943b598c935f309bBill Wendling I->getOpcode() == FrameDestroyOpcode) { 7536627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach#ifndef NDEBUG 7546627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach // Track whether we see even pairs of them 7556627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach SPAdjCount += I->getOpcode() == FrameSetupOpcode ? 1 : -1; 7566627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach#endif 757405abffd5eb1ad1841491e51943b598c935f309bBill Wendling // Remember how much SP has been adjusted to create the call 758405abffd5eb1ad1841491e51943b598c935f309bBill Wendling // frame. 75971a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner int Size = I->getOperand(0).getImm(); 760405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 76171a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner if ((!StackGrowsDown && I->getOpcode() == FrameSetupOpcode) || 76271a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner (StackGrowsDown && I->getOpcode() == FrameDestroyOpcode)) 76371a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner Size = -Size; 764988a5782d3ce3cddc65d57d6aac7312d33ed59abBill Wendling 76571a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner SPAdj += Size; 766405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 7675e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner MachineBasicBlock::iterator PrevI = BB->end(); 7685e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner if (I != BB->begin()) PrevI = prior(I); 769700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky TFI->eliminateCallFramePseudoInstr(Fn, *BB, I); 770405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 77171a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // Visit the instructions created by eliminateCallFramePseudoInstr(). 7725e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner if (PrevI == BB->end()) 7735e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner I = BB->begin(); // The replaced instr was the first in the block. 7745e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner else 7757896c9f436a4eda5ec15e882a7505ba482a2fcd0Chris Lattner I = llvm::next(PrevI); 77671a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner continue; 7778e3347332120956538a6d882b02719e34b57f0cdEvan Cheng } 778988a5782d3ce3cddc65d57d6aac7312d33ed59abBill Wendling 77978a5bd5dbd4d99d916c69d89ceaabd83c0e52469Evan Cheng MachineInstr *MI = I; 780405abffd5eb1ad1841491e51943b598c935f309bBill Wendling bool DoIncr = true; 7813ab115ce8f5262608630d67c28707dbd24361d03Chad Rosier for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 7825fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier if (!MI->getOperand(i).isFI()) 7836d9dbd5526e3161db884fc4fe99c278bb59ccc19David Blaikie continue; 7846d9dbd5526e3161db884fc4fe99c278bb59ccc19David Blaikie 7856d9dbd5526e3161db884fc4fe99c278bb59ccc19David Blaikie // Frame indicies in debug values are encoded in a target independent 7866d9dbd5526e3161db884fc4fe99c278bb59ccc19David Blaikie // way with simply the frame index and offset rather than any 7876d9dbd5526e3161db884fc4fe99c278bb59ccc19David Blaikie // target-specific addressing mode. 7886d9dbd5526e3161db884fc4fe99c278bb59ccc19David Blaikie if (MI->isDebugValue()) { 7896d9dbd5526e3161db884fc4fe99c278bb59ccc19David Blaikie assert(i == 0 && "Frame indicies can only appear as the first " 7906d9dbd5526e3161db884fc4fe99c278bb59ccc19David Blaikie "operand of a DBG_VALUE machine instruction"); 7916d9dbd5526e3161db884fc4fe99c278bb59ccc19David Blaikie unsigned Reg; 7926d9dbd5526e3161db884fc4fe99c278bb59ccc19David Blaikie MachineOperand &Offset = MI->getOperand(1); 7936d9dbd5526e3161db884fc4fe99c278bb59ccc19David Blaikie Offset.setImm(Offset.getImm() + 7946d9dbd5526e3161db884fc4fe99c278bb59ccc19David Blaikie TFI->getFrameIndexReference( 7956d9dbd5526e3161db884fc4fe99c278bb59ccc19David Blaikie Fn, MI->getOperand(0).getIndex(), Reg)); 7966d9dbd5526e3161db884fc4fe99c278bb59ccc19David Blaikie MI->getOperand(0).ChangeToRegister(Reg, false /*isDef*/); 7976d9dbd5526e3161db884fc4fe99c278bb59ccc19David Blaikie continue; 7986d9dbd5526e3161db884fc4fe99c278bb59ccc19David Blaikie } 7995fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier 8005fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier // Some instructions (e.g. inline asm instructions) can have 8015fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier // multiple frame indices and/or cause eliminateFrameIndex 8025fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier // to insert more than one instruction. We need the register 8035fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier // scavenger to go through all of these instructions so that 8045fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier // it can update its register information. We keep the 8055fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier // iterator at the point before insertion so that we can 8065fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier // revisit them in full. 8075fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier bool AtBeginning = (I == BB->begin()); 8085fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier if (!AtBeginning) --I; 8095fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier 8105fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier // If this instruction has a FrameIndex operand, we need to 8115fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier // use that target machine register info object to eliminate 8125fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier // it. 8135fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier TRI.eliminateFrameIndex(MI, SPAdj, i, 8145fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier FrameIndexVirtualScavenging ? NULL : RS); 8155fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier 8165fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier // Reset the iterator if we were at the beginning of the BB. 8175fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier if (AtBeginning) { 8185fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier I = BB->begin(); 8195fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier DoIncr = false; 82071a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner } 8215fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier 8225fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier MI = 0; 8235fb7947ed16a57a9c0b71ac70905454d82d25696Chad Rosier break; 8243ab115ce8f5262608630d67c28707dbd24361d03Chad Rosier } 825405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 8268fc2d0ee8dd4e077ee90a1fcc36fd0101c2947a2Chris Lattner if (DoIncr && I != BB->end()) ++I; 827405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 82849dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng // Update register states. 8293d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach if (RS && !FrameIndexVirtualScavenging && MI) RS->forward(MI); 83049dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng } 831988a5782d3ce3cddc65d57d6aac7312d33ed59abBill Wendling 8326627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach // If we have evenly matched pairs of frame setup / destroy instructions, 8336627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach // make sure the adjustments come out to zero. If we don't have matched 8346627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach // pairs, we can't be sure the missing bit isn't in another basic block 8356627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach // due to a custom inserter playing tricks, so just asserting SPAdj==0 8366627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach // isn't sufficient. See tMOVCC on Thumb1, for example. 8376627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach assert((SPAdjCount || SPAdj == 0) && 8386627ac040a14f3a79564fd6ec030f9361f81d20eJim Grosbach "Unbalanced call frame setup / destroy pairs?"); 83949dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng } 84058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner} 841b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 8429a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach/// scavengeFrameVirtualRegs - Replace all frame index virtual registers 8439a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach/// with physical registers. Use the register scavenger to find an 8449a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach/// appropriate register to use. 84519273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick/// 84619273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick/// FIXME: Iterating over the instruction stream is unnecessary. We can simply 84719273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick/// iterate over the vreg use list, which at this point only contains machine 84819273aec441411b4d571fdb87c6daa0fbe7a33a0Andrew Trick/// operands for which eliminateFrameIndex need a new scratch reg. 8493d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbachvoid PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) { 8503d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach // Run through the instructions and find any virtual registers. 8513d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach for (MachineFunction::iterator BB = Fn.begin(), 8523d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach E = Fn.end(); BB != E; ++BB) { 8533d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach RS->enterBasicBlock(BB); 8543d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach 855e40bf5f9f40a4672cd55bfa51c64a4bb6f4b2f8fJim Grosbach int SPAdj = 0; 8563d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach 857b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbach // The instruction stream may change in the loop, so check BB->end() 858b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbach // directly. 859332553768242e82383df61d9161d1a665bfb3122Jim Grosbach for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) { 8602e80991a7712d51f7637513703fc896f93eea252Hal Finkel // We might end up here again with a NULL iterator if we scavenged a 8612e80991a7712d51f7637513703fc896f93eea252Hal Finkel // register for which we inserted spill code for definition by what was 8622e80991a7712d51f7637513703fc896f93eea252Hal Finkel // originally the first instruction in BB. 8632e80991a7712d51f7637513703fc896f93eea252Hal Finkel if (I == MachineBasicBlock::iterator(NULL)) 8642e80991a7712d51f7637513703fc896f93eea252Hal Finkel I = BB->begin(); 8652e80991a7712d51f7637513703fc896f93eea252Hal Finkel 8663d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach MachineInstr *MI = I; 8678846129f6eb58982a2cac22306c8c9b586084475Hal Finkel MachineBasicBlock::iterator J = llvm::next(I); 8682e80991a7712d51f7637513703fc896f93eea252Hal Finkel MachineBasicBlock::iterator P = I == BB->begin() ? 8692e80991a7712d51f7637513703fc896f93eea252Hal Finkel MachineBasicBlock::iterator(NULL) : llvm::prior(I); 8708846129f6eb58982a2cac22306c8c9b586084475Hal Finkel 8718846129f6eb58982a2cac22306c8c9b586084475Hal Finkel // RS should process this instruction before we might scavenge at this 8728846129f6eb58982a2cac22306c8c9b586084475Hal Finkel // location. This is because we might be replacing a virtual register 8738846129f6eb58982a2cac22306c8c9b586084475Hal Finkel // defined by this instruction, and if so, registers killed by this 8748846129f6eb58982a2cac22306c8c9b586084475Hal Finkel // instruction are available, and defined registers are not. 8758846129f6eb58982a2cac22306c8c9b586084475Hal Finkel RS->forward(I); 8768846129f6eb58982a2cac22306c8c9b586084475Hal Finkel 877332553768242e82383df61d9161d1a665bfb3122Jim Grosbach for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 8783d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach if (MI->getOperand(i).isReg()) { 879b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbach MachineOperand &MO = MI->getOperand(i); 880b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbach unsigned Reg = MO.getReg(); 88132030fe021ee614df6fdd77a2228e0e265049f3dJim Grosbach if (Reg == 0) 8829a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach continue; 883700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach if (!TargetRegisterInfo::isVirtualRegister(Reg)) 88432030fe021ee614df6fdd77a2228e0e265049f3dJim Grosbach continue; 885c52b3cced8aebbc665021ec6b8bcd0974c4ad7aeJim Grosbach 8868846129f6eb58982a2cac22306c8c9b586084475Hal Finkel // When we first encounter a new virtual register, it 8878846129f6eb58982a2cac22306c8c9b586084475Hal Finkel // must be a definition. 8888846129f6eb58982a2cac22306c8c9b586084475Hal Finkel assert(MI->getOperand(i).isDef() && 8898846129f6eb58982a2cac22306c8c9b586084475Hal Finkel "frame index virtual missing def!"); 8908846129f6eb58982a2cac22306c8c9b586084475Hal Finkel // Scavenge a new scratch register 8918846129f6eb58982a2cac22306c8c9b586084475Hal Finkel const TargetRegisterClass *RC = Fn.getRegInfo().getRegClass(Reg); 8928846129f6eb58982a2cac22306c8c9b586084475Hal Finkel unsigned ScratchReg = RS->scavengeRegister(RC, J, SPAdj); 8938846129f6eb58982a2cac22306c8c9b586084475Hal Finkel 8948846129f6eb58982a2cac22306c8c9b586084475Hal Finkel ++NumScavengedRegs; 8958846129f6eb58982a2cac22306c8c9b586084475Hal Finkel 896c0c7c2b6061e7ca2d528bbedadb1bea0561c9158Jim Grosbach // Replace this reference to the virtual register with the 897332553768242e82383df61d9161d1a665bfb3122Jim Grosbach // scratch register. 898700f5df518452162de7dda7461917f88e8f4c56eJim Grosbach assert (ScratchReg && "Missing scratch register!"); 8998846129f6eb58982a2cac22306c8c9b586084475Hal Finkel Fn.getRegInfo().replaceRegWith(Reg, ScratchReg); 9009a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach 9018846129f6eb58982a2cac22306c8c9b586084475Hal Finkel // Because this instruction was processed by the RS before this 9028846129f6eb58982a2cac22306c8c9b586084475Hal Finkel // register was allocated, make sure that the RS now records the 9038846129f6eb58982a2cac22306c8c9b586084475Hal Finkel // register as being used. 9048846129f6eb58982a2cac22306c8c9b586084475Hal Finkel RS->setUsed(ScratchReg); 9053d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach } 906332553768242e82383df61d9161d1a665bfb3122Jim Grosbach } 9078846129f6eb58982a2cac22306c8c9b586084475Hal Finkel 9088846129f6eb58982a2cac22306c8c9b586084475Hal Finkel // If the scavenger needed to use one of its spill slots, the 9098846129f6eb58982a2cac22306c8c9b586084475Hal Finkel // spill code will have been inserted in between I and J. This is a 9108846129f6eb58982a2cac22306c8c9b586084475Hal Finkel // problem because we need the spill code before I: Move I to just 9118846129f6eb58982a2cac22306c8c9b586084475Hal Finkel // prior to J. 9128846129f6eb58982a2cac22306c8c9b586084475Hal Finkel if (I != llvm::prior(J)) { 9132e80991a7712d51f7637513703fc896f93eea252Hal Finkel BB->splice(J, BB, I); 9142e80991a7712d51f7637513703fc896f93eea252Hal Finkel 9152e80991a7712d51f7637513703fc896f93eea252Hal Finkel // Before we move I, we need to prepare the RS to visit I again. 9162e80991a7712d51f7637513703fc896f93eea252Hal Finkel // Specifically, RS will assert if it sees uses of registers that 9172e80991a7712d51f7637513703fc896f93eea252Hal Finkel // it believes are undefined. Because we have already processed 9182e80991a7712d51f7637513703fc896f93eea252Hal Finkel // register kills in I, when it visits I again, it will believe that 9192e80991a7712d51f7637513703fc896f93eea252Hal Finkel // those registers are undefined. To avoid this situation, unprocess 9202e80991a7712d51f7637513703fc896f93eea252Hal Finkel // the instruction I. 9212e80991a7712d51f7637513703fc896f93eea252Hal Finkel assert(RS->getCurrentPosition() == I && 9222e80991a7712d51f7637513703fc896f93eea252Hal Finkel "The register scavenger has an unexpected position"); 9232e80991a7712d51f7637513703fc896f93eea252Hal Finkel I = P; 9242e80991a7712d51f7637513703fc896f93eea252Hal Finkel RS->unprocess(P); 9258846129f6eb58982a2cac22306c8c9b586084475Hal Finkel } else 9268846129f6eb58982a2cac22306c8c9b586084475Hal Finkel ++I; 9273d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach } 9283d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach } 9293d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach} 930