PrologEpilogInserter.cpp revision 9a0b6e6ded68db772631c2938c7a07905e28144f
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 22752c1df73949438ef6fa86a86363ee7091aa2532John Mosby#include "PrologEpilogInserter.h" 23ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby#include "llvm/CodeGen/MachineDominators.h" 24ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby#include "llvm/CodeGen/MachineLoopInfo.h" 2558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner#include "llvm/CodeGen/MachineInstr.h" 26eb24db9727a7babe863d5afe70c7bda3a460da18Chris Lattner#include "llvm/CodeGen/MachineFrameInfo.h" 2784bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner#include "llvm/CodeGen/MachineModuleInfo.h" 2884bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner#include "llvm/CodeGen/MachineRegisterInfo.h" 2949dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng#include "llvm/CodeGen/RegisterScavenging.h" 3058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner#include "llvm/Target/TargetMachine.h" 316f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman#include "llvm/Target/TargetRegisterInfo.h" 328bd66e690779c838db51f55cf0b31d7206b3b659Chris Lattner#include "llvm/Target/TargetFrameInfo.h" 333501feab811c86c9659248a4875fc31a3165f84dChris Lattner#include "llvm/Target/TargetInstrInfo.h" 343d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach#include "llvm/Support/CommandLine.h" 35a4f0b3a084d120cfc5b5bb06f64b222f5cb72740Chris Lattner#include "llvm/Support/Compiler.h" 363d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach#include "llvm/ADT/IndexedMap.h" 378e3347332120956538a6d882b02719e34b57f0cdEvan Cheng#include "llvm/ADT/STLExtras.h" 38c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng#include <climits> 39ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 4005d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattnerusing namespace llvm; 41d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 42378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosbychar PEI::ID = 0; 43b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 44378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosbystatic RegisterPass<PEI> 45378553cb079aba2b8dee5d52b5166316d4132d5aJohn MosbyX("prologepilog", "Prologue/Epilogue Insertion"); 46b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 473d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach// FIXME: For now, the frame index scavenging is off by default and only 483d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach// used by the Thumb1 target. When it's the default and replaces the current 493d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach// on-the-fly PEI scavenging for all targets, requiresRegisterScavenging() 503d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach// will replace this. 513d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbachcl::opt<bool> 523d6cb88a64fe67064de206405951eb326d86fc0cJim GrosbachFrameIndexVirtualScavenging("enable-frame-index-scavenging", 533d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach cl::Hidden, 543d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach cl::desc("Enable frame index elimination with" 553d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach "virtual register scavenging")); 563d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach 5758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// createPrologEpilogCodeInserter - This function returns a pass that inserts 5858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// prolog and epilog code, and eliminates abstract frame references. 5958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// 6005d8350c12d8d81de1d8af6f7da155bc1c1da50eChris LattnerFunctionPass *llvm::createPrologEpilogCodeInserter() { return new PEI(); } 6158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 62378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby/// runOnMachineFunction - Insert prolog/epilog code and replace abstract 63378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby/// frame indexes with appropriate references. 64b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby/// 65378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosbybool PEI::runOnMachineFunction(MachineFunction &Fn) { 66c5ec8a78ea898087ad361e5b755f74a76150e5fdAnton Korobeynikov const Function* F = Fn.getFunction(); 67b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo(); 68378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby RS = TRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : NULL; 69378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 70378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // Get MachineModuleInfo so that we can track the construction of the 71378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // frame. 72378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby if (MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>()) 73378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby Fn.getFrameInfo()->setMachineModuleInfo(MMI); 74378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 7533b350bf24be396a127c81af045468765731afc7Anton Korobeynikov // Calculate the MaxCallFrameSize and HasCalls variables for the function's 7633b350bf24be396a127c81af045468765731afc7Anton Korobeynikov // frame information. Also eliminates call frame pseudo instructions. 7733b350bf24be396a127c81af045468765731afc7Anton Korobeynikov calculateCallsInformation(Fn); 7833b350bf24be396a127c81af045468765731afc7Anton Korobeynikov 79378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // Allow the target machine to make some adjustments to the function 80378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // e.g. UsedPhysRegs before calculateCalleeSavedRegisters. 81378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby TRI->processFunctionBeforeCalleeSavedScan(Fn, RS); 82378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 8333b350bf24be396a127c81af045468765731afc7Anton Korobeynikov // Scan the function for modified callee saved registers and insert spill code 8433b350bf24be396a127c81af045468765731afc7Anton Korobeynikov // for any callee saved registers that are modified. 85378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby calculateCalleeSavedRegisters(Fn); 86378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 87378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // Determine placement of CSR spill/restore code: 88378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // - with shrink wrapping, place spills and restores to tightly 89378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // enclose regions in the Machine CFG of the function where 90378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // they are used. Without shrink wrapping 91378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // - default (no shrink wrapping), place all spills in the 92378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // entry block, all restores in return blocks. 93378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby placeCSRSpillsAndRestores(Fn); 94378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 95378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // Add the code to save and restore the callee saved registers 96c5ec8a78ea898087ad361e5b755f74a76150e5fdAnton Korobeynikov if (!F->hasFnAttr(Attribute::Naked)) 97c5ec8a78ea898087ad361e5b755f74a76150e5fdAnton Korobeynikov insertCSRSpillsAndRestores(Fn); 98378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 99378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // Allow the target machine to make final modifications to the function 100378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // before the frame layout is finalized. 101378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby TRI->processFunctionBeforeFrameFinalized(Fn); 102378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 103378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // Calculate actual frame offsets for all abstract stack objects... 104378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby calculateFrameObjectOffsets(Fn); 105378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 106378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // Add prolog and epilog code to the function. This function is required 107378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // to align the stack frame as necessary for any stack variables or 108378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // called functions. Because of this, calculateCalleeSavedRegisters 109378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // must be called before this function in order to set the HasCalls 110378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // and MaxCallFrameSize variables. 111c5ec8a78ea898087ad361e5b755f74a76150e5fdAnton Korobeynikov if (!F->hasFnAttr(Attribute::Naked)) 112c5ec8a78ea898087ad361e5b755f74a76150e5fdAnton Korobeynikov insertPrologEpilogCode(Fn); 113378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby 114378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // Replace all MO_FrameIndex operands with physical register references 115378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // and actual offsets. 116378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby // 117378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby replaceFrameIndices(Fn); 118b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 1193d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach // If register scavenging is needed, as we've enabled doing it as a 1203d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach // post-pass, scavenge the virtual registers that frame index elimiation 1213d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach // inserted. 1223d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach if (TRI->requiresRegisterScavenging(Fn) && FrameIndexVirtualScavenging) 1233d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach scavengeFrameVirtualRegs(Fn); 1243d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach 125378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby delete RS; 126378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby clearAllSets(); 127b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby return true; 128ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby} 129ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 130378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby#if 0 131378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosbyvoid PEI::getAnalysisUsage(AnalysisUsage &AU) const { 132845012e6d31799c7fbd1193fa1af8ee2d12e9231Dan Gohman AU.setPreservesCFG(); 133378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby if (ShrinkWrapping || ShrinkWrapFunc != "") { 134378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby AU.addRequired<MachineLoopInfo>(); 135378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby AU.addRequired<MachineDominatorTree>(); 136b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } 137378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby AU.addPreserved<MachineLoopInfo>(); 138378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby AU.addPreserved<MachineDominatorTree>(); 139378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby MachineFunctionPass::getAnalysisUsage(AU); 140ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby} 141378553cb079aba2b8dee5d52b5166316d4132d5aJohn Mosby#endif 142ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 14333b350bf24be396a127c81af045468765731afc7Anton Korobeynikov/// calculateCallsInformation - Calculate the MaxCallFrameSize and HasCalls 14433b350bf24be396a127c81af045468765731afc7Anton Korobeynikov/// variables for the function's frame information and eliminate call frame 14533b350bf24be396a127c81af045468765731afc7Anton Korobeynikov/// pseudo instructions. 14633b350bf24be396a127c81af045468765731afc7Anton Korobeynikovvoid PEI::calculateCallsInformation(MachineFunction &Fn) { 1476f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); 14858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 14933b350bf24be396a127c81af045468765731afc7Anton Korobeynikov unsigned MaxCallFrameSize = 0; 15033b350bf24be396a127c81af045468765731afc7Anton Korobeynikov bool HasCalls = false; 15158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 15258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Get the function call frame set-up and tear-down instruction opcode 15358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner int FrameSetupOpcode = RegInfo->getCallFrameSetupOpcode(); 15458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner int FrameDestroyOpcode = RegInfo->getCallFrameDestroyOpcode(); 15558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 15633b350bf24be396a127c81af045468765731afc7Anton Korobeynikov // Early exit for targets which have no call frame setup/destroy pseudo 15733b350bf24be396a127c81af045468765731afc7Anton Korobeynikov // instructions. 15833b350bf24be396a127c81af045468765731afc7Anton Korobeynikov if (FrameSetupOpcode == -1 && FrameDestroyOpcode == -1) 15958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner return; 16058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 1615c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng std::vector<MachineBasicBlock::iterator> FrameSDOps; 16258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) 1635c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) 164c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos if (I->getOpcode() == FrameSetupOpcode || 165d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner I->getOpcode() == FrameDestroyOpcode) { 1662a82ef317c39ac436f80854c7ddbb06bfddeada1Chris Lattner assert(I->getNumOperands() >= 1 && "Call Frame Setup/Destroy Pseudo" 167d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner " instructions should have a single immediate argument!"); 1689e3304900ff69c4920fea7369c9c36916c4a6a6aChris Lattner unsigned Size = I->getOperand(0).getImm(); 169d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner if (Size > MaxCallFrameSize) MaxCallFrameSize = Size; 170d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner HasCalls = true; 1715c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng FrameSDOps.push_back(I); 172423ccfe51daa699a969cd716ce3a69cb2ada6234Dale Johannesen } else if (I->getOpcode() == TargetInstrInfo::INLINEASM) { 173423ccfe51daa699a969cd716ce3a69cb2ada6234Dale Johannesen // An InlineAsm might be a call; assume it is to get the stack frame 174423ccfe51daa699a969cd716ce3a69cb2ada6234Dale Johannesen // aligned correctly for calls. 175423ccfe51daa699a969cd716ce3a69cb2ada6234Dale Johannesen HasCalls = true; 17658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 17758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 178eb24db9727a7babe863d5afe70c7bda3a460da18Chris Lattner MachineFrameInfo *FFI = Fn.getFrameInfo(); 17958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner FFI->setHasCalls(HasCalls); 18058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner FFI->setMaxCallFrameSize(MaxCallFrameSize); 1818e3347332120956538a6d882b02719e34b57f0cdEvan Cheng 182058a024eb7265239d527680b0a448cdb48102a46Bill Wendling for (std::vector<MachineBasicBlock::iterator>::iterator 183058a024eb7265239d527680b0a448cdb48102a46Bill Wendling i = FrameSDOps.begin(), e = FrameSDOps.end(); i != e; ++i) { 184058a024eb7265239d527680b0a448cdb48102a46Bill Wendling MachineBasicBlock::iterator I = *i; 185058a024eb7265239d527680b0a448cdb48102a46Bill Wendling 186058a024eb7265239d527680b0a448cdb48102a46Bill Wendling // If call frames are not being included as part of the stack frame, and 187058a024eb7265239d527680b0a448cdb48102a46Bill Wendling // there is no dynamic allocation (therefore referencing frame slots off 188058a024eb7265239d527680b0a448cdb48102a46Bill Wendling // sp), leave the pseudo ops alone. We'll eliminate them later. 1898e3347332120956538a6d882b02719e34b57f0cdEvan Cheng if (RegInfo->hasReservedCallFrame(Fn) || RegInfo->hasFP(Fn)) 1908e3347332120956538a6d882b02719e34b57f0cdEvan Cheng RegInfo->eliminateCallFramePseudoInstr(Fn, *I->getParent(), I); 1915c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng } 19233b350bf24be396a127c81af045468765731afc7Anton Korobeynikov} 19333b350bf24be396a127c81af045468765731afc7Anton Korobeynikov 19433b350bf24be396a127c81af045468765731afc7Anton Korobeynikov 19533b350bf24be396a127c81af045468765731afc7Anton Korobeynikov/// calculateCalleeSavedRegisters - Scan the function for modified callee saved 19633b350bf24be396a127c81af045468765731afc7Anton Korobeynikov/// registers. 19733b350bf24be396a127c81af045468765731afc7Anton Korobeynikovvoid PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) { 19833b350bf24be396a127c81af045468765731afc7Anton Korobeynikov const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); 19933b350bf24be396a127c81af045468765731afc7Anton Korobeynikov const TargetFrameInfo *TFI = Fn.getTarget().getFrameInfo(); 20033b350bf24be396a127c81af045468765731afc7Anton Korobeynikov MachineFrameInfo *FFI = Fn.getFrameInfo(); 20133b350bf24be396a127c81af045468765731afc7Anton Korobeynikov 20233b350bf24be396a127c81af045468765731afc7Anton Korobeynikov // Get the callee saved register list... 20333b350bf24be396a127c81af045468765731afc7Anton Korobeynikov const unsigned *CSRegs = RegInfo->getCalleeSavedRegs(&Fn); 20433b350bf24be396a127c81af045468765731afc7Anton Korobeynikov 20533b350bf24be396a127c81af045468765731afc7Anton Korobeynikov // These are used to keep track the callee-save area. Initialize them. 20633b350bf24be396a127c81af045468765731afc7Anton Korobeynikov MinCSFrameIndex = INT_MAX; 20733b350bf24be396a127c81af045468765731afc7Anton Korobeynikov MaxCSFrameIndex = 0; 20833b350bf24be396a127c81af045468765731afc7Anton Korobeynikov 20933b350bf24be396a127c81af045468765731afc7Anton Korobeynikov // Early exit for targets which have no callee saved registers. 21033b350bf24be396a127c81af045468765731afc7Anton Korobeynikov if (CSRegs == 0 || CSRegs[0] == 0) 21133b350bf24be396a127c81af045468765731afc7Anton Korobeynikov return; 21258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 21333b350bf24be396a127c81af045468765731afc7Anton Korobeynikov // Figure out which *callee saved* registers are modified by the current 21458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // function, thus needing to be saved and restored in the prolog/epilog. 215058a024eb7265239d527680b0a448cdb48102a46Bill Wendling const TargetRegisterClass * const *CSRegClasses = 2162365f51ed03afe6993bae962fdc2e5a956a64cd5Anton Korobeynikov RegInfo->getCalleeSavedRegClasses(&Fn); 217058a024eb7265239d527680b0a448cdb48102a46Bill Wendling 21808ede262a744f99429658fadb43662441bdcb42dJim Laskey std::vector<CalleeSavedInfo> CSI; 21958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner for (unsigned i = 0; CSRegs[i]; ++i) { 22058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner unsigned Reg = CSRegs[i]; 2212afb3b7251dbcfadef7a8126e9516bde78fc13bbJim Grosbach if (Fn.getRegInfo().isPhysRegUsed(Reg)) { 222058a024eb7265239d527680b0a448cdb48102a46Bill Wendling // If the reg is modified, save it! 223f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey CSI.push_back(CalleeSavedInfo(Reg, CSRegClasses[i])); 22473ff5120eb8b8c0ccbfed8a17f1024c67a75f319Alkis Evlogimenos } else { 22573ff5120eb8b8c0ccbfed8a17f1024c67a75f319Alkis Evlogimenos for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg); 2263563015b0df358cfc4ec310eb0df195015ea54a5Chris Lattner *AliasSet; ++AliasSet) { // Check alias registers too. 22784bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner if (Fn.getRegInfo().isPhysRegUsed(*AliasSet)) { 228f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey CSI.push_back(CalleeSavedInfo(Reg, CSRegClasses[i])); 229d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner break; 230ecf8afdc2065dec1ca739e2b6a96f8e72dc34533Chris Lattner } 23173ff5120eb8b8c0ccbfed8a17f1024c67a75f319Alkis Evlogimenos } 23273ff5120eb8b8c0ccbfed8a17f1024c67a75f319Alkis Evlogimenos } 23358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 23458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 235f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey if (CSI.empty()) 236c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng return; // Early exit if no callee saved registers are modified! 23758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 238c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner unsigned NumFixedSpillSlots; 2398ff95de83cbe85d939535d2f4fb5f9b2b721081aTilmann Scheller const TargetFrameInfo::SpillSlot *FixedSpillSlots = 240ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng TFI->getCalleeSavedSpillSlots(NumFixedSpillSlots); 241c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 24258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Now that we know which registers need to be saved and restored, allocate 24358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // stack slots for them. 244058a024eb7265239d527680b0a448cdb48102a46Bill Wendling for (std::vector<CalleeSavedInfo>::iterator 245058a024eb7265239d527680b0a448cdb48102a46Bill Wendling I = CSI.begin(), E = CSI.end(); I != E; ++I) { 246058a024eb7265239d527680b0a448cdb48102a46Bill Wendling unsigned Reg = I->getReg(); 247058a024eb7265239d527680b0a448cdb48102a46Bill Wendling const TargetRegisterClass *RC = I->getRegClass(); 248c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 249910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng int FrameIdx; 250910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng if (RegInfo->hasReservedSpillSlot(Fn, Reg, FrameIdx)) { 251910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng I->setFrameIdx(FrameIdx); 252910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng continue; 253910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng } 254910139f9ca53fc20a680d51ae61bb1e072095141Evan Cheng 255c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // Check to see if this physreg must be spilled to a particular stack slot 256c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // on this target. 2578ff95de83cbe85d939535d2f4fb5f9b2b721081aTilmann Scheller const TargetFrameInfo::SpillSlot *FixedSlot = FixedSpillSlots; 258c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner while (FixedSlot != FixedSpillSlots+NumFixedSpillSlots && 2598ff95de83cbe85d939535d2f4fb5f9b2b721081aTilmann Scheller FixedSlot->Reg != Reg) 260c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner ++FixedSlot; 261c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 262058a024eb7265239d527680b0a448cdb48102a46Bill Wendling if (FixedSlot == FixedSpillSlots + NumFixedSpillSlots) { 263c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // Nope, just spill it anywhere convenient. 2645feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng unsigned Align = RC->getAlignment(); 2655feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng unsigned StackAlign = TFI->getStackAlignment(); 266058a024eb7265239d527680b0a448cdb48102a46Bill Wendling 267058a024eb7265239d527680b0a448cdb48102a46Bill Wendling // We may not be able to satisfy the desired alignment specification of 268058a024eb7265239d527680b0a448cdb48102a46Bill Wendling // the TargetRegisterClass if the stack alignment is smaller. Use the 269058a024eb7265239d527680b0a448cdb48102a46Bill Wendling // min. 2705feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng Align = std::min(Align, StackAlign); 2715feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng FrameIdx = FFI->CreateStackObject(RC->getSize(), Align); 272c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng if ((unsigned)FrameIdx < MinCSFrameIndex) MinCSFrameIndex = FrameIdx; 273c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng if ((unsigned)FrameIdx > MaxCSFrameIndex) MaxCSFrameIndex = FrameIdx; 274c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner } else { 275c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // Spill it to the stack where we must. 2768ff95de83cbe85d939535d2f4fb5f9b2b721081aTilmann Scheller FrameIdx = FFI->CreateFixedObject(RC->getSize(), FixedSlot->Offset); 277c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner } 278058a024eb7265239d527680b0a448cdb48102a46Bill Wendling 279058a024eb7265239d527680b0a448cdb48102a46Bill Wendling I->setFrameIdx(FrameIdx); 28058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 28108ede262a744f99429658fadb43662441bdcb42dJim Laskey 28208ede262a744f99429658fadb43662441bdcb42dJim Laskey FFI->setCalleeSavedInfo(CSI); 283c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner} 284c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 285ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby/// insertCSRSpillsAndRestores - Insert spill and restore code for 286ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby/// callee saved registers used in the function, handling shrink wrapping. 287c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner/// 288ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosbyvoid PEI::insertCSRSpillsAndRestores(MachineFunction &Fn) { 289f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey // Get callee saved register information. 290f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey MachineFrameInfo *FFI = Fn.getFrameInfo(); 29108ede262a744f99429658fadb43662441bdcb42dJim Laskey const std::vector<CalleeSavedInfo> &CSI = FFI->getCalleeSavedInfo(); 292ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 293d62c9a697b53f9e754926a89126fd121220ed09bJakob Stoklund Olesen FFI->setCalleeSavedInfoValid(true); 294d62c9a697b53f9e754926a89126fd121220ed09bJakob Stoklund Olesen 295c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Early exit if no callee saved registers are modified! 296f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey if (CSI.empty()) 297edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman return; 298c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 299f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); 300ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby MachineBasicBlock::iterator I; 30100dff8dda29b5a249cd99405ce26e84cef13ba53Evan Cheng 302b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby if (! ShrinkWrapThisFunction) { 303b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // Spill using target interface. 304b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby I = EntryBlock->begin(); 305b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby if (!TII.spillCalleeSavedRegisters(*EntryBlock, I, CSI)) { 306b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 307ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // Add the callee-saved register as live-in. 308ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // It's killed at the spill. 309b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby EntryBlock->addLiveIn(CSI[i].getReg()); 310ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 311ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // Insert the spill to the stack frame. 312b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby TII.storeRegToStackSlot(*EntryBlock, I, CSI[i].getReg(), true, 313b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby CSI[i].getFrameIdx(), CSI[i].getRegClass()); 314ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby } 315ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng } 316ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 317b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // Restore using target interface. 318b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby for (unsigned ri = 0, re = ReturnBlocks.size(); ri != re; ++ri) { 319b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby MachineBasicBlock* MBB = ReturnBlocks[ri]; 320c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos I = MBB->end(); --I; 32158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 322f7c094000f4baf094b1d60ba68a5b4e0193c502aBill Wendling // Skip over all terminator instructions, which are part of the return 3234fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner // sequence. 3244fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner MachineBasicBlock::iterator I2 = I; 325f7c094000f4baf094b1d60ba68a5b4e0193c502aBill Wendling while (I2 != MBB->begin() && (--I2)->getDesc().isTerminator()) 3264fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner I = I2; 3274fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner 328dfd58709cc78e841ef4a50ba75d940473031617eChris Lattner bool AtStart = I == MBB->begin(); 329ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner MachineBasicBlock::iterator BeforeI = I; 330ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner if (!AtStart) 331ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner --BeforeI; 332ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 333ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // Restore all registers immediately before the return and any 334ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // terminators that preceed it. 335a393cd3306b865e8e5d82dc4e6cfabcdf5d8dc44Owen Anderson if (!TII.restoreCalleeSavedRegisters(*MBB, I, CSI)) { 336ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 337f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson TII.loadRegFromStackSlot(*MBB, I, CSI[i].getReg(), 338ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby CSI[i].getFrameIdx(), 339ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby CSI[i].getRegClass()); 340ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng assert(I != MBB->begin() && 341ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng "loadRegFromStackSlot didn't insert any code!"); 342ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // Insert in reverse order. loadRegFromStackSlot can insert 343ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // multiple instructions. 344ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng if (AtStart) 345ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng I = MBB->begin(); 346ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng else { 347ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng I = BeforeI; 348ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng ++I; 349ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng } 350ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner } 35158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 352b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } 353b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby return; 354b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } 355ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 356b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // Insert spills. 357b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby std::vector<CalleeSavedInfo> blockCSI; 358b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby for (CSRegBlockMap::iterator BI = CSRSave.begin(), 359b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby BE = CSRSave.end(); BI != BE; ++BI) { 360b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby MachineBasicBlock* MBB = BI->first; 361b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby CSRegSet save = BI->second; 362ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 363b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby if (save.empty()) 364b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby continue; 365ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 366b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby blockCSI.clear(); 367b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby for (CSRegSet::iterator RI = save.begin(), 368b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby RE = save.end(); RI != RE; ++RI) { 369b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby blockCSI.push_back(CSI[*RI]); 370b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } 371b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby assert(blockCSI.size() > 0 && 372b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby "Could not collect callee saved register info"); 373b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 374b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby I = MBB->begin(); 375b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 376b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // When shrink wrapping, use stack slot stores/loads. 377b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby for (unsigned i = 0, e = blockCSI.size(); i != e; ++i) { 378b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // Add the callee-saved register as live-in. 379b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // It's killed at the spill. 380b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby MBB->addLiveIn(blockCSI[i].getReg()); 381b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 382b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // Insert the spill to the stack frame. 383b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby TII.storeRegToStackSlot(*MBB, I, blockCSI[i].getReg(), 384b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby true, 385b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby blockCSI[i].getFrameIdx(), 386b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby blockCSI[i].getRegClass()); 387b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } 388b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } 389b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 390b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby for (CSRegBlockMap::iterator BI = CSRRestore.begin(), 391b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby BE = CSRRestore.end(); BI != BE; ++BI) { 392b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby MachineBasicBlock* MBB = BI->first; 393b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby CSRegSet restore = BI->second; 394b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 395b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby if (restore.empty()) 396b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby continue; 397b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 398b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby blockCSI.clear(); 399b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby for (CSRegSet::iterator RI = restore.begin(), 400b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby RE = restore.end(); RI != RE; ++RI) { 401b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby blockCSI.push_back(CSI[*RI]); 402b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } 403b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby assert(blockCSI.size() > 0 && 404b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby "Could not find callee saved register info"); 405b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 406b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // If MBB is empty and needs restores, insert at the _beginning_. 407b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby if (MBB->empty()) { 408b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby I = MBB->begin(); 409b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } else { 410b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby I = MBB->end(); 411b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby --I; 412b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 413b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // Skip over all terminator instructions, which are part of the 414b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // return sequence. 415b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby if (! I->getDesc().isTerminator()) { 416b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby ++I; 417ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby } else { 418b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby MachineBasicBlock::iterator I2 = I; 419b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby while (I2 != MBB->begin() && (--I2)->getDesc().isTerminator()) 420b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby I = I2; 421ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby } 422b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby } 423ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 424b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby bool AtStart = I == MBB->begin(); 425b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby MachineBasicBlock::iterator BeforeI = I; 426b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby if (!AtStart) 427b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby --BeforeI; 428b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 429b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // Restore all registers immediately before the return and any 430b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // terminators that preceed it. 431b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby for (unsigned i = 0, e = blockCSI.size(); i != e; ++i) { 432b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby TII.loadRegFromStackSlot(*MBB, I, blockCSI[i].getReg(), 433b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby blockCSI[i].getFrameIdx(), 434b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby blockCSI[i].getRegClass()); 435b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby assert(I != MBB->begin() && 436b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby "loadRegFromStackSlot didn't insert any code!"); 437b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // Insert in reverse order. loadRegFromStackSlot can insert 438b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby // multiple instructions. 439b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby if (AtStart) 440b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby I = MBB->begin(); 441b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby else { 442b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby I = BeforeI; 443b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby ++I; 444ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby } 44558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 446ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby } 44758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner} 44858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 449cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling/// AdjustStackOffset - Helper function used to adjust the stack frame offset. 450cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendlingstatic inline void 451cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill WendlingAdjustStackOffset(MachineFrameInfo *FFI, int FrameIdx, 452cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling bool StackGrowsDown, int64_t &Offset, 453cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling unsigned &MaxAlign) { 45494188d4e67cf1c570ad87dbabf198931033d628eBob Wilson // If the stack grows down, add the object size to find the lowest address. 455cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling if (StackGrowsDown) 456cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling Offset += FFI->getObjectSize(FrameIdx); 457cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling 458cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling unsigned Align = FFI->getObjectAlignment(FrameIdx); 459cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling 460cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling // If the alignment of this object is greater than that of the stack, then 461cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling // increase the stack alignment to match. 462cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling MaxAlign = std::max(MaxAlign, Align); 463cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling 464cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling // Adjust to alignment boundary. 465cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling Offset = (Offset + Align - 1) / Align * Align; 466cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling 467cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling if (StackGrowsDown) { 468cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling FFI->setObjectOffset(FrameIdx, -Offset); // Set the computed offset 469cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling } else { 470cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling FFI->setObjectOffset(FrameIdx, Offset); 471cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling Offset += FFI->getObjectSize(FrameIdx); 472cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling } 473cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling} 47458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 47558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the 47692b9fcea7b3180ed18f379212d14bd5cea7a1954Chris Lattner/// abstract stack objects. 47758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// 47858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattnervoid PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { 4799bcdcd17c7219dbc68de2f11ca2de86471c8c390Chris Lattner const TargetFrameInfo &TFI = *Fn.getTarget().getFrameInfo(); 480edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 48158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner bool StackGrowsDown = 48258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner TFI.getStackGrowthDirection() == TargetFrameInfo::StackGrowsDown; 483edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 48458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Loop over all of the stack objects, assigning sequential addresses... 485eb24db9727a7babe863d5afe70c7bda3a460da18Chris Lattner MachineFrameInfo *FFI = Fn.getFrameInfo(); 48658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 4870035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson unsigned MaxAlign = 1; 48878d6db5627bdf41ab3ffd96133821647dbc60d53Chris Lattner 48905d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner // Start at the beginning of the local area. 490577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // The Offset is the distance from the stack top in the direction 491c0d6012b31afa2220306afa27db1b02e18427776Dan Gohman // of stack growth -- so it's always nonnegative. 492c34666ee1871d47dfa4865c7138902dd1b770101Bob Wilson int LocalAreaOffset = TFI.getOffsetOfLocalArea(); 493577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner if (StackGrowsDown) 494c34666ee1871d47dfa4865c7138902dd1b770101Bob Wilson LocalAreaOffset = -LocalAreaOffset; 495c34666ee1871d47dfa4865c7138902dd1b770101Bob Wilson assert(LocalAreaOffset >= 0 496577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner && "Local area offset should be in direction of stack growth"); 497c34666ee1871d47dfa4865c7138902dd1b770101Bob Wilson int64_t Offset = LocalAreaOffset; 498577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner 499577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // If there are fixed sized objects that are preallocated in the local area, 500577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // non-fixed objects can't be allocated right at the start of local area. 501ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // We currently don't support filling in holes in between fixed sized 502ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // objects, so we adjust 'Offset' to point to the end of last fixed sized 50305d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner // preallocated object. 50405d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) { 505a401b1e1c5eb9563617db8a2477b4c5f8b239521Chris Lattner int64_t FixedOff; 506577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner if (StackGrowsDown) { 507577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // The maximum distance from the stack pointer is at lower address of 508577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // the object -- which is given by offset. For down growing stack 509577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // the offset is negative, so we negate the offset to get the distance. 510577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner FixedOff = -FFI->getObjectOffset(i); 511577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner } else { 512edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman // The maximum distance from the start pointer is at the upper 513577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // address of the object. 514577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner FixedOff = FFI->getObjectOffset(i) + FFI->getObjectSize(i); 515edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman } 516edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman if (FixedOff > Offset) Offset = FixedOff; 51705d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner } 51805d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner 519c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // First assign frame offsets to stack objects that are used to spill 520ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng // callee saved registers. 521c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng if (StackGrowsDown) { 5225c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng for (unsigned i = MinCSFrameIndex; i <= MaxCSFrameIndex; ++i) { 523c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // If stack grows down, we need to add size of find the lowest 524c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // address of the object. 525c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng Offset += FFI->getObjectSize(i); 526c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 527c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng unsigned Align = FFI->getObjectAlignment(i); 528ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // If the alignment of this object is greater than that of the stack, 529ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // then increase the stack alignment to match. 530c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng MaxAlign = std::max(MaxAlign, Align); 531c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Adjust to alignment boundary 532c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng Offset = (Offset+Align-1)/Align*Align; 533c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 534c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng FFI->setObjectOffset(i, -Offset); // Set the computed offset 535c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng } 536c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng } else { 537a8c63f0fc9feb48f17d702a907f065959c41e337Bruno Cardoso Lopes int MaxCSFI = MaxCSFrameIndex, MinCSFI = MinCSFrameIndex; 538a8c63f0fc9feb48f17d702a907f065959c41e337Bruno Cardoso Lopes for (int i = MaxCSFI; i >= MinCSFI ; --i) { 539c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng unsigned Align = FFI->getObjectAlignment(i); 540ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // If the alignment of this object is greater than that of the stack, 541ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby // then increase the stack alignment to match. 542c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng MaxAlign = std::max(MaxAlign, Align); 543c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Adjust to alignment boundary 544c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng Offset = (Offset+Align-1)/Align*Align; 545c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 546c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng FFI->setObjectOffset(i, Offset); 547c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng Offset += FFI->getObjectSize(i); 548c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng } 549c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng } 550c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 55187f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // Make sure the special register scavenging spill slot is closest to the 55287f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // frame pointer if a frame pointer is required. 5536f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); 55487f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng if (RS && RegInfo->hasFP(Fn)) { 55587f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng int SFI = RS->getScavengingFrameIndex(); 556cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling if (SFI >= 0) 557cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling AdjustStackOffset(FFI, SFI, StackGrowsDown, Offset, MaxAlign); 55887f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng } 55987f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 560b2a4298ce41e7ef80cd75a3c1dfa6433f0759a1aBill Wendling // Make sure that the stack protector comes before the local variables on the 561b2a4298ce41e7ef80cd75a3c1dfa6433f0759a1aBill Wendling // stack. 562cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling if (FFI->getStackProtectorIndex() >= 0) 563cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling AdjustStackOffset(FFI, FFI->getStackProtectorIndex(), StackGrowsDown, 564cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling Offset, MaxAlign); 565b2a4298ce41e7ef80cd75a3c1dfa6433f0759a1aBill Wendling 566c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Then assign frame offsets to stack objects that are not used to spill 567ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng // callee saved registers. 56858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) { 569c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex) 570c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng continue; 57187f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng if (RS && (int)i == RS->getScavengingFrameIndex()) 57287f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng continue; 573d36531249a9a9500e516148e7e72d4c0a7a4d0eeEvan Cheng if (FFI->isDeadObjectIndex(i)) 574d36531249a9a9500e516148e7e72d4c0a7a4d0eeEvan Cheng continue; 57544cf38c01ff610139d2e8dbbdc4e6123a3debcddBill Wendling if (FFI->getStackProtectorIndex() == (int)i) 57644cf38c01ff610139d2e8dbbdc4e6123a3debcddBill Wendling continue; 577c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 578cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling AdjustStackOffset(FFI, i, StackGrowsDown, Offset, MaxAlign); 57958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 58058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 58187f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // Make sure the special register scavenging spill slot is closest to the 58287f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // stack pointer. 5838d410b69384ae4e178b3b522ef3357290a714de5Lauro Ramos Venancio if (RS && !RegInfo->hasFP(Fn)) { 58487f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng int SFI = RS->getScavengingFrameIndex(); 585cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling if (SFI >= 0) 586cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling AdjustStackOffset(FFI, SFI, StackGrowsDown, Offset, MaxAlign); 58787f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng } 58887f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 5890035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson if (!RegInfo->targetHandlesStackFrameRounding()) { 5905c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng // If we have reserved argument space for call sites in the function 5915c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng // immediately on entry to the current function, count it as part of the 5925c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng // overall stack size. 5930035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson if (FFI->hasCalls() && RegInfo->hasReservedCallFrame(Fn)) 594367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng Offset += FFI->getMaxCallFrameSize(); 595367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng 5960035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson // Round up the size to a multiple of the alignment. If the function has 5970035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson // any calls or alloca's, align to the target's StackAlignment value to 5980035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson // ensure that the callee's frame or the alloca data is suitably aligned; 5990035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson // otherwise, for leaf functions, align to the TransientStackAlignment 6000035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson // value. 6010035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson unsigned StackAlign; 6020035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson if (FFI->hasCalls() || FFI->hasVarSizedObjects() || 6030035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson (RegInfo->needsStackRealignment(Fn) && FFI->getObjectIndexEnd() != 0)) 6040035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson StackAlign = TFI.getStackAlignment(); 6050035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson else 6060035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson StackAlign = TFI.getTransientStackAlignment(); 6070035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson // If the frame pointer is eliminated, all frame offsets will be relative 6080035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson // to SP not FP; align to MaxAlign so this works. 6090035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson StackAlign = std::max(StackAlign, MaxAlign); 6100035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson unsigned AlignMask = StackAlign - 1; 611ea84c5ee952c62dd0c703c9852d7a60715e4a435Chris Lattner Offset = (Offset + AlignMask) & ~uint64_t(AlignMask); 612367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng } 613367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng 614367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng // Update frame info to pretend that this is part of the stack... 615c34666ee1871d47dfa4865c7138902dd1b770101Bob Wilson FFI->setStackSize(Offset - LocalAreaOffset); 616cbef8ba5f959b3c4f932005ceef5cf2e0d899f9bChris Lattner 617cbef8ba5f959b3c4f932005ceef5cf2e0d899f9bChris Lattner // Remember the required stack alignment in case targets need it to perform 618cbef8ba5f959b3c4f932005ceef5cf2e0d899f9bChris Lattner // dynamic stack alignment. 6190035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson if (MaxAlign > FFI->getMaxAlignment()) 6200035f9c3b9982eeef098b608fceb7572df969b3eBob Wilson FFI->setMaxAlignment(MaxAlign); 6214ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner} 6224ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner 6234ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner 624c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng/// insertPrologEpilogCode - Scan the function for modified callee saved 625c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng/// registers, insert spill code for these callee saved registers, then add 6264ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner/// prolog and epilog code to the function. 6274ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner/// 6284ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattnervoid PEI::insertPrologEpilogCode(MachineFunction &Fn) { 629874384e20f618d6ac932628db64e048757213fcdAnton Korobeynikov const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo(); 630874384e20f618d6ac932628db64e048757213fcdAnton Korobeynikov 6314ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner // Add prologue to the function... 632874384e20f618d6ac932628db64e048757213fcdAnton Korobeynikov TRI->emitPrologue(Fn); 6334ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner 6344ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner // Add epilogue to restore the callee-save registers in each exiting block 6354ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) { 6364ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner // If last instruction is a return instruction, add an epilogue 637749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner if (!I->empty() && I->back().getDesc().isReturn()) 638874384e20f618d6ac932628db64e048757213fcdAnton Korobeynikov TRI->emitEpilogue(Fn, *I); 6394ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner } 64058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner} 64158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 64258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 64358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// replaceFrameIndices - Replace all MO_FrameIndex operands with physical 64458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// register references and actual offsets. 64558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// 64658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattnervoid PEI::replaceFrameIndices(MachineFunction &Fn) { 64758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner if (!Fn.getFrameInfo()->hasStackObjects()) return; // Nothing to do? 64858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 64958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner const TargetMachine &TM = Fn.getTarget(); 65058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner assert(TM.getRegisterInfo() && "TM::getRegisterInfo() must be implemented!"); 6516f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman const TargetRegisterInfo &TRI = *TM.getRegisterInfo(); 6528e3347332120956538a6d882b02719e34b57f0cdEvan Cheng const TargetFrameInfo *TFI = TM.getFrameInfo(); 6538e3347332120956538a6d882b02719e34b57f0cdEvan Cheng bool StackGrowsDown = 6548e3347332120956538a6d882b02719e34b57f0cdEvan Cheng TFI->getStackGrowthDirection() == TargetFrameInfo::StackGrowsDown; 6556f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman int FrameSetupOpcode = TRI.getCallFrameSetupOpcode(); 6566f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman int FrameDestroyOpcode = TRI.getCallFrameDestroyOpcode(); 65758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 658ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby for (MachineFunction::iterator BB = Fn.begin(), 659ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby E = Fn.end(); BB != E; ++BB) { 6608e3347332120956538a6d882b02719e34b57f0cdEvan Cheng int SPAdj = 0; // SP offset due to call frame setup / destroy. 6613d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach if (RS && !FrameIndexVirtualScavenging) RS->enterBasicBlock(BB); 662ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 6630ebe9c132c6b9c74b334f0c7503e702b499575d5Chris Lattner for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) { 664405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 665405abffd5eb1ad1841491e51943b598c935f309bBill Wendling if (I->getOpcode() == FrameSetupOpcode || 666405abffd5eb1ad1841491e51943b598c935f309bBill Wendling I->getOpcode() == FrameDestroyOpcode) { 667405abffd5eb1ad1841491e51943b598c935f309bBill Wendling // Remember how much SP has been adjusted to create the call 668405abffd5eb1ad1841491e51943b598c935f309bBill Wendling // frame. 66971a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner int Size = I->getOperand(0).getImm(); 670405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 67171a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner if ((!StackGrowsDown && I->getOpcode() == FrameSetupOpcode) || 67271a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner (StackGrowsDown && I->getOpcode() == FrameDestroyOpcode)) 67371a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner Size = -Size; 674988a5782d3ce3cddc65d57d6aac7312d33ed59abBill Wendling 67571a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner SPAdj += Size; 676405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 6775e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner MachineBasicBlock::iterator PrevI = BB->end(); 6785e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner if (I != BB->begin()) PrevI = prior(I); 67971a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner TRI.eliminateCallFramePseudoInstr(Fn, *BB, I); 680405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 68171a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // Visit the instructions created by eliminateCallFramePseudoInstr(). 6825e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner if (PrevI == BB->end()) 6835e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner I = BB->begin(); // The replaced instr was the first in the block. 6845e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner else 6855e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner I = next(PrevI); 68671a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner continue; 6878e3347332120956538a6d882b02719e34b57f0cdEvan Cheng } 688988a5782d3ce3cddc65d57d6aac7312d33ed59abBill Wendling 68978a5bd5dbd4d99d916c69d89ceaabd83c0e52469Evan Cheng MachineInstr *MI = I; 690405abffd5eb1ad1841491e51943b598c935f309bBill Wendling bool DoIncr = true; 691405abffd5eb1ad1841491e51943b598c935f309bBill Wendling for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) 692d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman if (MI->getOperand(i).isFI()) { 69371a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // Some instructions (e.g. inline asm instructions) can have 69471a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // multiple frame indices and/or cause eliminateFrameIndex 69571a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // to insert more than one instruction. We need the register 69671a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // scavenger to go through all of these instructions so that 69771a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // it can update its register information. We keep the 69871a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // iterator at the point before insertion so that we can 69971a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // revisit them in full. 70071a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner bool AtBeginning = (I == BB->begin()); 70171a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner if (!AtBeginning) --I; 70271a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner 70371a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // If this instruction has a FrameIndex operand, we need to 70471a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // use that target machine register info object to eliminate 70571a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // it. 706ea4d351fc690bd6558fe9ca61db88ee809f0572fJohn Mosby 7073d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach TRI.eliminateFrameIndex(MI, SPAdj, FrameIndexVirtualScavenging ? 7083d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach NULL : RS); 70971a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner 71071a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // Reset the iterator if we were at the beginning of the BB. 71171a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner if (AtBeginning) { 71271a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner I = BB->begin(); 71371a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner DoIncr = false; 71471a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner } 71571a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner 71671a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner MI = 0; 71771a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner break; 71871a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner } 719405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 7208fc2d0ee8dd4e077ee90a1fcc36fd0101c2947a2Chris Lattner if (DoIncr && I != BB->end()) ++I; 721405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 72249dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng // Update register states. 7233d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach if (RS && !FrameIndexVirtualScavenging && MI) RS->forward(MI); 72449dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng } 725988a5782d3ce3cddc65d57d6aac7312d33ed59abBill Wendling 7268e3347332120956538a6d882b02719e34b57f0cdEvan Cheng assert(SPAdj == 0 && "Unbalanced call frame setup / destroy pairs?"); 72749dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng } 72858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner} 729b9cfbd94abb23ec8646b9b10aa4ac3d1cbf4461eJohn Mosby 7309a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach/// scavengeFrameVirtualRegs - Replace all frame index virtual registers 7319a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach/// with physical registers. Use the register scavenger to find an 7329a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach/// appropriate register to use. 7333d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbachvoid PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) { 7343d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo(); 7353d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach 7363d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach // Run through the instructions and find any virtual registers. 7373d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach for (MachineFunction::iterator BB = Fn.begin(), 7383d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach E = Fn.end(); BB != E; ++BB) { 7393d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach RS->enterBasicBlock(BB); 7403d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach 7419a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach unsigned CurrentVirtReg = 0; 7429a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach unsigned CurrentScratchReg; 7433d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach 7443d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) { 7453d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach MachineInstr *MI = I; 7463d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) 7473d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach if (MI->getOperand(i).isReg()) { 7483d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach unsigned Reg = MI->getOperand(i).getReg(); 7499a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach if (Reg == 0 || !TRI->isVirtualRegister(Reg)) 7509a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach continue; 7519a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach 7529a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach // If we already have a scratch for this virtual register, use it 7539a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach if (Reg != CurrentVirtReg) { 7549a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach // When we first encounter a new virtual register, it 7559a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach // must be a definition. 7569a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach assert(MI->getOperand(i).isDef() && 7579a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach "frame index virtual missing def!"); 7589a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach // We can't have nested virtual register live ranges because 7599a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach // there's only a guarantee of one scavenged register at a time. 7609a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach assert (CurrentVirtReg == 0 && 7619a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach "overlapping frame index virtual registers!"); 7629a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach CurrentVirtReg = Reg; 7639a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach const TargetRegisterClass *RC = Fn.getRegInfo().getRegClass(Reg); 7649a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach CurrentScratchReg = RS->FindUnusedReg(RC); 7659a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach if (CurrentScratchReg == 0) 7669a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach // No register is "free". Scavenge a register. 7679a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach // FIXME: Track SPAdj. Zero won't always be right 7689a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach CurrentScratchReg = RS->scavengeRegister(RC, I, 0); 7693d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach } 7709a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach assert (CurrentScratchReg && "Missing scratch register!"); 7719a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach MI->getOperand(i).setReg(CurrentScratchReg); 7729a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach 7739a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach // If this is the last use of the register, stop tracking it. 7749a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach if (MI->getOperand(i).isKill()) 7759a0b6e6ded68db772631c2938c7a07905e28144fJim Grosbach CurrentVirtReg = 0; 7763d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach } 7773d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach RS->forward(MI); 7783d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach } 7793d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach } 7803d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach} 781