PrologEpilogInserter.cpp revision 5e6345bde0f3a6405ec1ea852f1e5e5df8642f9c
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// 1758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner//===----------------------------------------------------------------------===// 1858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 19f00a3f905e8cd99ab4d3dbbde1a9d510516e0fa2Chris Lattner#include "llvm/CodeGen/Passes.h" 20f00a3f905e8cd99ab4d3dbbde1a9d510516e0fa2Chris Lattner#include "llvm/CodeGen/MachineFunctionPass.h" 2158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner#include "llvm/CodeGen/MachineInstr.h" 22eb24db9727a7babe863d5afe70c7bda3a460da18Chris Lattner#include "llvm/CodeGen/MachineFrameInfo.h" 2384bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner#include "llvm/CodeGen/MachineModuleInfo.h" 2484bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner#include "llvm/CodeGen/MachineRegisterInfo.h" 2549dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng#include "llvm/CodeGen/RegisterScavenging.h" 2658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner#include "llvm/Target/TargetMachine.h" 276f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman#include "llvm/Target/TargetRegisterInfo.h" 288bd66e690779c838db51f55cf0b31d7206b3b659Chris Lattner#include "llvm/Target/TargetFrameInfo.h" 293501feab811c86c9659248a4875fc31a3165f84dChris Lattner#include "llvm/Target/TargetInstrInfo.h" 30a4f0b3a084d120cfc5b5bb06f64b222f5cb72740Chris Lattner#include "llvm/Support/Compiler.h" 318e3347332120956538a6d882b02719e34b57f0cdEvan Cheng#include "llvm/ADT/STLExtras.h" 32c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng#include <climits> 3305d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattnerusing namespace llvm; 34d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 3558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattnernamespace { 36f8c68f694c25b1ae8c0e5adb2a19432cb405d232Chris Lattner struct VISIBILITY_HIDDEN PEI : public MachineFunctionPass { 371997473cf72957d0e70322e2fe6fe2ab141c58a6Devang Patel static char ID; 38ae73dc1448d25b02cabc7c64c86c64371453dda8Dan Gohman PEI() : MachineFunctionPass(&ID) {} 39794fd75c67a2cdc128d67342c6d88a504d186896Devang Patel 40f00a3f905e8cd99ab4d3dbbde1a9d510516e0fa2Chris Lattner const char *getPassName() const { 41f00a3f905e8cd99ab4d3dbbde1a9d510516e0fa2Chris Lattner return "Prolog/Epilog Insertion & Frame Finalization"; 4258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 4358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 44bbeeb2a61ea19fbb5449260165b56c40fdc4860bEvan Cheng virtual void getAnalysisUsage(AnalysisUsage &AU) const { 458b56a90bec639665fc024896d2fc2bdd095c76a3Evan Cheng AU.addPreservedID(MachineLoopInfoID); 468b56a90bec639665fc024896d2fc2bdd095c76a3Evan Cheng AU.addPreservedID(MachineDominatorsID); 47bbeeb2a61ea19fbb5449260165b56c40fdc4860bEvan Cheng MachineFunctionPass::getAnalysisUsage(AU); 48bbeeb2a61ea19fbb5449260165b56c40fdc4860bEvan Cheng } 49bbeeb2a61ea19fbb5449260165b56c40fdc4860bEvan Cheng 5058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner /// runOnMachineFunction - Insert prolog/epilog code and replace abstract 5158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner /// frame indexes with appropriate references. 5258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner /// 5358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner bool runOnMachineFunction(MachineFunction &Fn) { 546f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo(); 556f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman RS = TRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : NULL; 5687f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 5744c3b9fdd416c79f4b67cde1aecfced5921efd81Jim Laskey // Get MachineModuleInfo so that we can track the construction of the 584188699f80c233a20b6ddc61570a8a8c1804cb85Jim Laskey // frame. 591465d61bdd36cfd6021036a527895f0dd358e97dDuncan Sands if (MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>()) 6044c3b9fdd416c79f4b67cde1aecfced5921efd81Jim Laskey Fn.getFrameInfo()->setMachineModuleInfo(MMI); 61c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 62c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Allow the target machine to make some adjustments to the function 63c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // e.g. UsedPhysRegs before calculateCalleeSavedRegisters. 646f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman TRI->processFunctionBeforeCalleeSavedScan(Fn, RS); 65c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 66692d4e0823774730b90e8e2d7bf58119397f0535Evan Cheng // Scan the function for modified callee saved registers and insert spill 67692d4e0823774730b90e8e2d7bf58119397f0535Evan Cheng // code for any callee saved registers that are modified. Also calculate 6858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // the MaxCallFrameSize and HasCalls variables for the function's frame 6958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // information and eliminates call frame pseudo instructions. 70692d4e0823774730b90e8e2d7bf58119397f0535Evan Cheng calculateCalleeSavedRegisters(Fn); 71c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 72c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Add the code to save and restore the callee saved registers 73c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng saveCalleeSavedRegisters(Fn); 7458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 7558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Allow the target machine to make final modifications to the function 7658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // before the frame layout is finalized. 77874384e20f618d6ac932628db64e048757213fcdAnton Korobeynikov TRI->processFunctionBeforeFrameFinalized(Fn); 7858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 7958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Calculate actual frame offsets for all of the abstract stack objects... 8058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner calculateFrameObjectOffsets(Fn); 8158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 82c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // Add prolog and epilog code to the function. This function is required 83c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // to align the stack frame as necessary for any stack variables or 84692d4e0823774730b90e8e2d7bf58119397f0535Evan Cheng // called functions. Because of this, calculateCalleeSavedRegisters 85c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // must be called before this function in order to set the HasCalls 86c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // and MaxCallFrameSize variables. 874ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner insertPrologEpilogCode(Fn); 884ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner 8958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Replace all MO_FrameIndex operands with physical register references 9058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // and actual offsets. 9158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // 9258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner replaceFrameIndices(Fn); 93c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 9487f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng delete RS; 9558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner return true; 9658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 97f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey 9858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner private: 9987f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng RegScavenger *RS; 10087f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 101ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng // MinCSFrameIndex, MaxCSFrameIndex - Keeps the range of callee saved 102c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // stack frame indexes. 103c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng unsigned MinCSFrameIndex, MaxCSFrameIndex; 104c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 105692d4e0823774730b90e8e2d7bf58119397f0535Evan Cheng void calculateCalleeSavedRegisters(MachineFunction &Fn); 106c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng void saveCalleeSavedRegisters(MachineFunction &Fn); 10758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner void calculateFrameObjectOffsets(MachineFunction &Fn); 10858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner void replaceFrameIndices(MachineFunction &Fn); 10958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner void insertPrologEpilogCode(MachineFunction &Fn); 11058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner }; 1111997473cf72957d0e70322e2fe6fe2ab141c58a6Devang Patel char PEI::ID = 0; 11258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner} 11358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 114d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 11558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// createPrologEpilogCodeInserter - This function returns a pass that inserts 11658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// prolog and epilog code, and eliminates abstract frame references. 11758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// 11805d8350c12d8d81de1d8af6f7da155bc1c1da50eChris LattnerFunctionPass *llvm::createPrologEpilogCodeInserter() { return new PEI(); } 11958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 12058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 121c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng/// calculateCalleeSavedRegisters - Scan the function for modified callee saved 122c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner/// registers. Also calculate the MaxCallFrameSize and HasCalls variables for 12358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// the function's frame information and eliminates call frame pseudo 12458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// instructions. 12558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// 126692d4e0823774730b90e8e2d7bf58119397f0535Evan Chengvoid PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) { 1276f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); 128c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner const TargetFrameInfo *TFI = Fn.getTarget().getFrameInfo(); 12958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 13058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Get the callee saved register list... 1312365f51ed03afe6993bae962fdc2e5a956a64cd5Anton Korobeynikov const unsigned *CSRegs = RegInfo->getCalleeSavedRegs(&Fn); 13258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 13358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Get the function call frame set-up and tear-down instruction opcode 13458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner int FrameSetupOpcode = RegInfo->getCallFrameSetupOpcode(); 13558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner int FrameDestroyOpcode = RegInfo->getCallFrameDestroyOpcode(); 13658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 1377d3223eef2982d7acdfb24facde6605fd9a8b5e8Evan Cheng // These are used to keep track the callee-save area. Initialize them. 1387d3223eef2982d7acdfb24facde6605fd9a8b5e8Evan Cheng MinCSFrameIndex = INT_MAX; 1397d3223eef2982d7acdfb24facde6605fd9a8b5e8Evan Cheng MaxCSFrameIndex = 0; 1407d3223eef2982d7acdfb24facde6605fd9a8b5e8Evan Cheng 14158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Early exit for targets which have no callee saved registers and no call 14258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // frame setup/destroy pseudo instructions. 14358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner if ((CSRegs == 0 || CSRegs[0] == 0) && 14458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner FrameSetupOpcode == -1 && FrameDestroyOpcode == -1) 14558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner return; 14658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 14758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner unsigned MaxCallFrameSize = 0; 14858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner bool HasCalls = false; 14958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 1505c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng std::vector<MachineBasicBlock::iterator> FrameSDOps; 15158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) 1525c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) 153c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos if (I->getOpcode() == FrameSetupOpcode || 154d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner I->getOpcode() == FrameDestroyOpcode) { 1552a82ef317c39ac436f80854c7ddbb06bfddeada1Chris Lattner assert(I->getNumOperands() >= 1 && "Call Frame Setup/Destroy Pseudo" 156d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner " instructions should have a single immediate argument!"); 1579e3304900ff69c4920fea7369c9c36916c4a6a6aChris Lattner unsigned Size = I->getOperand(0).getImm(); 158d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner if (Size > MaxCallFrameSize) MaxCallFrameSize = Size; 159d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner HasCalls = true; 1605c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng FrameSDOps.push_back(I); 16158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 16258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 163eb24db9727a7babe863d5afe70c7bda3a460da18Chris Lattner MachineFrameInfo *FFI = Fn.getFrameInfo(); 16458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner FFI->setHasCalls(HasCalls); 16558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner FFI->setMaxCallFrameSize(MaxCallFrameSize); 1668e3347332120956538a6d882b02719e34b57f0cdEvan Cheng 1675c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng for (unsigned i = 0, e = FrameSDOps.size(); i != e; ++i) { 1685c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng MachineBasicBlock::iterator I = FrameSDOps[i]; 1698e3347332120956538a6d882b02719e34b57f0cdEvan Cheng // If call frames are not being included as part of the stack frame, 1708e3347332120956538a6d882b02719e34b57f0cdEvan Cheng // and there is no dynamic allocation (therefore referencing frame slots 1718e3347332120956538a6d882b02719e34b57f0cdEvan Cheng // off sp), leave the pseudo ops alone. We'll eliminate them later. 1728e3347332120956538a6d882b02719e34b57f0cdEvan Cheng if (RegInfo->hasReservedCallFrame(Fn) || RegInfo->hasFP(Fn)) 1738e3347332120956538a6d882b02719e34b57f0cdEvan Cheng RegInfo->eliminateCallFramePseudoInstr(Fn, *I->getParent(), I); 1745c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng } 17558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 17658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Now figure out which *callee saved* registers are modified by the current 17758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // function, thus needing to be saved and restored in the prolog/epilog. 17858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // 17980a4f169b4a8cd160f832fd4a1052e5d9b2c1a92Chris Lattner const TargetRegisterClass* const *CSRegClasses = 1802365f51ed03afe6993bae962fdc2e5a956a64cd5Anton Korobeynikov RegInfo->getCalleeSavedRegClasses(&Fn); 18108ede262a744f99429658fadb43662441bdcb42dJim Laskey std::vector<CalleeSavedInfo> CSI; 18258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner for (unsigned i = 0; CSRegs[i]; ++i) { 18358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner unsigned Reg = CSRegs[i]; 18484bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner if (Fn.getRegInfo().isPhysRegUsed(Reg)) { 18580a4f169b4a8cd160f832fd4a1052e5d9b2c1a92Chris Lattner // If the reg is modified, save it! 186f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey CSI.push_back(CalleeSavedInfo(Reg, CSRegClasses[i])); 18773ff5120eb8b8c0ccbfed8a17f1024c67a75f319Alkis Evlogimenos } else { 18873ff5120eb8b8c0ccbfed8a17f1024c67a75f319Alkis Evlogimenos for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg); 1893563015b0df358cfc4ec310eb0df195015ea54a5Chris Lattner *AliasSet; ++AliasSet) { // Check alias registers too. 19084bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner if (Fn.getRegInfo().isPhysRegUsed(*AliasSet)) { 191f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey CSI.push_back(CalleeSavedInfo(Reg, CSRegClasses[i])); 192d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner break; 193ecf8afdc2065dec1ca739e2b6a96f8e72dc34533Chris Lattner } 19473ff5120eb8b8c0ccbfed8a17f1024c67a75f319Alkis Evlogimenos } 19573ff5120eb8b8c0ccbfed8a17f1024c67a75f319Alkis Evlogimenos } 19658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 19758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 198f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey if (CSI.empty()) 199c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng return; // Early exit if no callee saved registers are modified! 20058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 201c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner unsigned NumFixedSpillSlots; 2028c9b4de5744ea6c4ce8b79e8a55130df268761cdAlkis Evlogimenos const std::pair<unsigned,int> *FixedSpillSlots = 203ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng TFI->getCalleeSavedSpillSlots(NumFixedSpillSlots); 204c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 20558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Now that we know which registers need to be saved and restored, allocate 20658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // stack slots for them. 207f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 208f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey unsigned Reg = CSI[i].getReg(); 209f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey const TargetRegisterClass *RC = CSI[i].getRegClass(); 210c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 211c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // Check to see if this physreg must be spilled to a particular stack slot 212c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // on this target. 2138c9b4de5744ea6c4ce8b79e8a55130df268761cdAlkis Evlogimenos const std::pair<unsigned,int> *FixedSlot = FixedSpillSlots; 214c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner while (FixedSlot != FixedSpillSlots+NumFixedSpillSlots && 215c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner FixedSlot->first != Reg) 216c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner ++FixedSlot; 217c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 218fa1face30a1943aa17560f6f6e10bb667b257065Chris Lattner int FrameIdx; 219c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner if (FixedSlot == FixedSpillSlots+NumFixedSpillSlots) { 220c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // Nope, just spill it anywhere convenient. 2215feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng unsigned Align = RC->getAlignment(); 2225feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng unsigned StackAlign = TFI->getStackAlignment(); 2235feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng // We may not be able to sastify the desired alignment specification of 2245feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng // the TargetRegisterClass if the stack alignment is smaller. Use the min. 2255feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng Align = std::min(Align, StackAlign); 2265feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng FrameIdx = FFI->CreateStackObject(RC->getSize(), Align); 227c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng if ((unsigned)FrameIdx < MinCSFrameIndex) MinCSFrameIndex = FrameIdx; 228c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng if ((unsigned)FrameIdx > MaxCSFrameIndex) MaxCSFrameIndex = FrameIdx; 229c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner } else { 230c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // Spill it to the stack where we must. 2318fb040e584606f048b85d87363a52baf5ff9c1c7Chris Lattner FrameIdx = FFI->CreateFixedObject(RC->getSize(), FixedSlot->second); 232c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner } 233f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey CSI[i].setFrameIdx(FrameIdx); 23458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 23508ede262a744f99429658fadb43662441bdcb42dJim Laskey 23608ede262a744f99429658fadb43662441bdcb42dJim Laskey FFI->setCalleeSavedInfo(CSI); 237c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner} 238c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 239c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng/// saveCalleeSavedRegisters - Insert spill code for any callee saved registers 240c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner/// that are modified in the function. 241c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner/// 242c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Chengvoid PEI::saveCalleeSavedRegisters(MachineFunction &Fn) { 243f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey // Get callee saved register information. 244f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey MachineFrameInfo *FFI = Fn.getFrameInfo(); 24508ede262a744f99429658fadb43662441bdcb42dJim Laskey const std::vector<CalleeSavedInfo> &CSI = FFI->getCalleeSavedInfo(); 246f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey 247c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Early exit if no callee saved registers are modified! 248f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey if (CSI.empty()) 249edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman return; 250c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 251f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); 25200dff8dda29b5a249cd99405ce26e84cef13ba53Evan Cheng 25358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Now that we have a stack slot for each register to be saved, insert spill 25492b9fcea7b3180ed18f379212d14bd5cea7a1954Chris Lattner // code into the entry block. 25558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner MachineBasicBlock *MBB = Fn.begin(); 25658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner MachineBasicBlock::iterator I = MBB->begin(); 25700dff8dda29b5a249cd99405ce26e84cef13ba53Evan Cheng 258a393cd3306b865e8e5d82dc4e6cfabcdf5d8dc44Owen Anderson if (!TII.spillCalleeSavedRegisters(*MBB, I, CSI)) { 259ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 26049dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng // Add the callee-saved register as live-in. It's killed at the spill. 26149dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng MBB->addLiveIn(CSI[i].getReg()); 26249dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng 263ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng // Insert the spill to the stack frame. 264f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson TII.storeRegToStackSlot(*MBB, I, CSI[i].getReg(), true, 26549dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng CSI[i].getFrameIdx(), CSI[i].getRegClass()); 266ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng } 26758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 26858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 26958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Add code to restore the callee-save registers in each exiting block. 27092b9fcea7b3180ed18f379212d14bd5cea7a1954Chris Lattner for (MachineFunction::iterator FI = Fn.begin(), E = Fn.end(); FI != E; ++FI) 27192b9fcea7b3180ed18f379212d14bd5cea7a1954Chris Lattner // If last instruction is a return instruction, add an epilogue. 272749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner if (!FI->empty() && FI->back().getDesc().isReturn()) { 273c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos MBB = FI; 274c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos I = MBB->end(); --I; 27558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 276f7c094000f4baf094b1d60ba68a5b4e0193c502aBill Wendling // Skip over all terminator instructions, which are part of the return 2774fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner // sequence. 2784fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner MachineBasicBlock::iterator I2 = I; 279f7c094000f4baf094b1d60ba68a5b4e0193c502aBill Wendling while (I2 != MBB->begin() && (--I2)->getDesc().isTerminator()) 2804fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner I = I2; 2814fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner 282dfd58709cc78e841ef4a50ba75d940473031617eChris Lattner bool AtStart = I == MBB->begin(); 283ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner MachineBasicBlock::iterator BeforeI = I; 284ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner if (!AtStart) 285ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner --BeforeI; 286ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner 2874fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner // Restore all registers immediately before the return and any terminators 2884fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner // that preceed it. 289a393cd3306b865e8e5d82dc4e6cfabcdf5d8dc44Owen Anderson if (!TII.restoreCalleeSavedRegisters(*MBB, I, CSI)) { 290ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 291f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson TII.loadRegFromStackSlot(*MBB, I, CSI[i].getReg(), 292ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng CSI[i].getFrameIdx(), 293ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng CSI[i].getRegClass()); 294ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng assert(I != MBB->begin() && 295ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng "loadRegFromStackSlot didn't insert any code!"); 296ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng // Insert in reverse order. loadRegFromStackSlot can insert multiple 297ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng // instructions. 298ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng if (AtStart) 299ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng I = MBB->begin(); 300ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng else { 301ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng I = BeforeI; 302ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng ++I; 303ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng } 304ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner } 30558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 30658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 30758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner} 30858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 309cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling/// AdjustStackOffset - Helper function used to adjust the stack frame offset. 310cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendlingstatic inline void 311cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill WendlingAdjustStackOffset(MachineFrameInfo *FFI, int FrameIdx, 312cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling bool StackGrowsDown, int64_t &Offset, 313cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling unsigned &MaxAlign) { 314cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling // If stack grows down, we need to add size of find the lowest address of the 315cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling // object. 316cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling if (StackGrowsDown) 317cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling Offset += FFI->getObjectSize(FrameIdx); 318cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling 319cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling unsigned Align = FFI->getObjectAlignment(FrameIdx); 320cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling 321cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling // If the alignment of this object is greater than that of the stack, then 322cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling // increase the stack alignment to match. 323cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling MaxAlign = std::max(MaxAlign, Align); 324cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling 325cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling // Adjust to alignment boundary. 326cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling Offset = (Offset + Align - 1) / Align * Align; 327cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling 328cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling if (StackGrowsDown) { 329cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling FFI->setObjectOffset(FrameIdx, -Offset); // Set the computed offset 330cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling } else { 331cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling FFI->setObjectOffset(FrameIdx, Offset); 332cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling Offset += FFI->getObjectSize(FrameIdx); 333cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling } 334cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling} 33558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 33658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the 33792b9fcea7b3180ed18f379212d14bd5cea7a1954Chris Lattner/// abstract stack objects. 33858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// 33958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattnervoid PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { 3409bcdcd17c7219dbc68de2f11ca2de86471c8c390Chris Lattner const TargetFrameInfo &TFI = *Fn.getTarget().getFrameInfo(); 341edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 34258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner bool StackGrowsDown = 34358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner TFI.getStackGrowthDirection() == TargetFrameInfo::StackGrowsDown; 344edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 34558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Loop over all of the stack objects, assigning sequential addresses... 346eb24db9727a7babe863d5afe70c7bda3a460da18Chris Lattner MachineFrameInfo *FFI = Fn.getFrameInfo(); 34758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 348aadc780a56820c263dca141b2b9f9e39355f6991Anton Korobeynikov unsigned MaxAlign = FFI->getMaxAlignment(); 34978d6db5627bdf41ab3ffd96133821647dbc60d53Chris Lattner 35005d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner // Start at the beginning of the local area. 351577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // The Offset is the distance from the stack top in the direction 352c0d6012b31afa2220306afa27db1b02e18427776Dan Gohman // of stack growth -- so it's always nonnegative. 353a401b1e1c5eb9563617db8a2477b4c5f8b239521Chris Lattner int64_t Offset = TFI.getOffsetOfLocalArea(); 354577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner if (StackGrowsDown) 3557f7bbc2fdb833485ac3d865a405fd948e58e8ddbChris Lattner Offset = -Offset; 356edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman assert(Offset >= 0 357577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner && "Local area offset should be in direction of stack growth"); 358577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner 359577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // If there are fixed sized objects that are preallocated in the local area, 360577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // non-fixed objects can't be allocated right at the start of local area. 361edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman // We currently don't support filling in holes in between fixed sized objects, 362577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // so we adjust 'Offset' to point to the end of last fixed sized 36305d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner // preallocated object. 36405d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) { 365a401b1e1c5eb9563617db8a2477b4c5f8b239521Chris Lattner int64_t FixedOff; 366577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner if (StackGrowsDown) { 367577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // The maximum distance from the stack pointer is at lower address of 368577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // the object -- which is given by offset. For down growing stack 369577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // the offset is negative, so we negate the offset to get the distance. 370577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner FixedOff = -FFI->getObjectOffset(i); 371577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner } else { 372edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman // The maximum distance from the start pointer is at the upper 373577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // address of the object. 374577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner FixedOff = FFI->getObjectOffset(i) + FFI->getObjectSize(i); 375edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman } 376edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman if (FixedOff > Offset) Offset = FixedOff; 37705d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner } 37805d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner 379c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // First assign frame offsets to stack objects that are used to spill 380ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng // callee saved registers. 381c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng if (StackGrowsDown) { 3825c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng for (unsigned i = MinCSFrameIndex; i <= MaxCSFrameIndex; ++i) { 383c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // If stack grows down, we need to add size of find the lowest 384c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // address of the object. 385c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng Offset += FFI->getObjectSize(i); 386c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 387c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng unsigned Align = FFI->getObjectAlignment(i); 388c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // If the alignment of this object is greater than that of the stack, then 389c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // increase the stack alignment to match. 390c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng MaxAlign = std::max(MaxAlign, Align); 391c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Adjust to alignment boundary 392c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng Offset = (Offset+Align-1)/Align*Align; 393c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 394c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng FFI->setObjectOffset(i, -Offset); // Set the computed offset 395c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng } 396c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng } else { 397a8c63f0fc9feb48f17d702a907f065959c41e337Bruno Cardoso Lopes int MaxCSFI = MaxCSFrameIndex, MinCSFI = MinCSFrameIndex; 398a8c63f0fc9feb48f17d702a907f065959c41e337Bruno Cardoso Lopes for (int i = MaxCSFI; i >= MinCSFI ; --i) { 399c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng unsigned Align = FFI->getObjectAlignment(i); 400c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // If the alignment of this object is greater than that of the stack, then 401c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // increase the stack alignment to match. 402c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng MaxAlign = std::max(MaxAlign, Align); 403c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Adjust to alignment boundary 404c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng Offset = (Offset+Align-1)/Align*Align; 405c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 406c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng FFI->setObjectOffset(i, Offset); 407c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng Offset += FFI->getObjectSize(i); 408c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng } 409c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng } 410c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 41187f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // Make sure the special register scavenging spill slot is closest to the 41287f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // frame pointer if a frame pointer is required. 4136f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); 41487f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng if (RS && RegInfo->hasFP(Fn)) { 41587f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng int SFI = RS->getScavengingFrameIndex(); 416cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling if (SFI >= 0) 417cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling AdjustStackOffset(FFI, SFI, StackGrowsDown, Offset, MaxAlign); 41887f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng } 41987f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 420b2a4298ce41e7ef80cd75a3c1dfa6433f0759a1aBill Wendling // Make sure that the stack protector comes before the local variables on the 421b2a4298ce41e7ef80cd75a3c1dfa6433f0759a1aBill Wendling // stack. 422cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling if (FFI->getStackProtectorIndex() >= 0) 423cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling AdjustStackOffset(FFI, FFI->getStackProtectorIndex(), StackGrowsDown, 424cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling Offset, MaxAlign); 425b2a4298ce41e7ef80cd75a3c1dfa6433f0759a1aBill Wendling 426c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Then assign frame offsets to stack objects that are not used to spill 427ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng // callee saved registers. 42858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) { 429c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex) 430c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng continue; 43187f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng if (RS && (int)i == RS->getScavengingFrameIndex()) 43287f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng continue; 433d36531249a9a9500e516148e7e72d4c0a7a4d0eeEvan Cheng if (FFI->isDeadObjectIndex(i)) 434d36531249a9a9500e516148e7e72d4c0a7a4d0eeEvan Cheng continue; 43544cf38c01ff610139d2e8dbbdc4e6123a3debcddBill Wendling if (FFI->getStackProtectorIndex() == (int)i) 43644cf38c01ff610139d2e8dbbdc4e6123a3debcddBill Wendling continue; 437c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 438cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling AdjustStackOffset(FFI, i, StackGrowsDown, Offset, MaxAlign); 43958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 44058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 44187f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // Make sure the special register scavenging spill slot is closest to the 44287f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // stack pointer. 4438d410b69384ae4e178b3b522ef3357290a714de5Lauro Ramos Venancio if (RS && !RegInfo->hasFP(Fn)) { 44487f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng int SFI = RS->getScavengingFrameIndex(); 445cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling if (SFI >= 0) 446cab3e68136b20a10cb0fe8ad97874bacf27dda7dBill Wendling AdjustStackOffset(FFI, SFI, StackGrowsDown, Offset, MaxAlign); 44787f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng } 44887f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 449367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng // Round up the size to a multiple of the alignment, but only if there are 450367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng // calls or alloca's in the function. This ensures that any calls to 451367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng // subroutines have their stack frames suitable aligned. 452b5dae003252d8e650a32bfdf33cba5aed8e41e40Dale Johannesen // Also do this if we need runtime alignment of the stack. In this case 453b5dae003252d8e650a32bfdf33cba5aed8e41e40Dale Johannesen // offsets will be relative to SP not FP; round up the stack size so this 454b5dae003252d8e650a32bfdf33cba5aed8e41e40Dale Johannesen // works. 45502a20291410a6814c657b69901a57103d4861a07Evan Cheng if (!RegInfo->targetHandlesStackFrameRounding() && 456b5dae003252d8e650a32bfdf33cba5aed8e41e40Dale Johannesen (FFI->hasCalls() || FFI->hasVarSizedObjects() || 457edec8d89dfaebd7050df4acafe3d01fa755ffd0dDale Johannesen (RegInfo->needsStackRealignment(Fn) && 458edec8d89dfaebd7050df4acafe3d01fa755ffd0dDale Johannesen FFI->getObjectIndexEnd() != 0))) { 4595c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng // If we have reserved argument space for call sites in the function 4605c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng // immediately on entry to the current function, count it as part of the 4615c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng // overall stack size. 4625c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng if (RegInfo->hasReservedCallFrame(Fn)) 463367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng Offset += FFI->getMaxCallFrameSize(); 464367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng 465b5dae003252d8e650a32bfdf33cba5aed8e41e40Dale Johannesen unsigned AlignMask = std::max(TFI.getStackAlignment(),MaxAlign) - 1; 466ea84c5ee952c62dd0c703c9852d7a60715e4a435Chris Lattner Offset = (Offset + AlignMask) & ~uint64_t(AlignMask); 467367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng } 468367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng 469367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng // Update frame info to pretend that this is part of the stack... 4707f7bbc2fdb833485ac3d865a405fd948e58e8ddbChris Lattner FFI->setStackSize(Offset+TFI.getOffsetOfLocalArea()); 471cbef8ba5f959b3c4f932005ceef5cf2e0d899f9bChris Lattner 472cbef8ba5f959b3c4f932005ceef5cf2e0d899f9bChris Lattner // Remember the required stack alignment in case targets need it to perform 473cbef8ba5f959b3c4f932005ceef5cf2e0d899f9bChris Lattner // dynamic stack alignment. 474be680dcea6858c438c6615326ae1c098ff448ae1Evan Cheng FFI->setMaxAlignment(MaxAlign); 4754ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner} 4764ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner 4774ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner 478c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng/// insertPrologEpilogCode - Scan the function for modified callee saved 479c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng/// registers, insert spill code for these callee saved registers, then add 4804ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner/// prolog and epilog code to the function. 4814ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner/// 4824ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattnervoid PEI::insertPrologEpilogCode(MachineFunction &Fn) { 483874384e20f618d6ac932628db64e048757213fcdAnton Korobeynikov const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo(); 484874384e20f618d6ac932628db64e048757213fcdAnton Korobeynikov 4854ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner // Add prologue to the function... 486874384e20f618d6ac932628db64e048757213fcdAnton Korobeynikov TRI->emitPrologue(Fn); 4874ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner 4884ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner // Add epilogue to restore the callee-save registers in each exiting block 4894ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) { 4904ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner // If last instruction is a return instruction, add an epilogue 491749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner if (!I->empty() && I->back().getDesc().isReturn()) 492874384e20f618d6ac932628db64e048757213fcdAnton Korobeynikov TRI->emitEpilogue(Fn, *I); 4934ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner } 49458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner} 49558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 49658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 49758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// replaceFrameIndices - Replace all MO_FrameIndex operands with physical 49858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// register references and actual offsets. 49958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// 50058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattnervoid PEI::replaceFrameIndices(MachineFunction &Fn) { 50158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner if (!Fn.getFrameInfo()->hasStackObjects()) return; // Nothing to do? 50258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 50358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner const TargetMachine &TM = Fn.getTarget(); 50458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner assert(TM.getRegisterInfo() && "TM::getRegisterInfo() must be implemented!"); 5056f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman const TargetRegisterInfo &TRI = *TM.getRegisterInfo(); 5068e3347332120956538a6d882b02719e34b57f0cdEvan Cheng const TargetFrameInfo *TFI = TM.getFrameInfo(); 5078e3347332120956538a6d882b02719e34b57f0cdEvan Cheng bool StackGrowsDown = 5088e3347332120956538a6d882b02719e34b57f0cdEvan Cheng TFI->getStackGrowthDirection() == TargetFrameInfo::StackGrowsDown; 5096f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman int FrameSetupOpcode = TRI.getCallFrameSetupOpcode(); 5106f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman int FrameDestroyOpcode = TRI.getCallFrameDestroyOpcode(); 51158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 51249dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) { 5138e3347332120956538a6d882b02719e34b57f0cdEvan Cheng int SPAdj = 0; // SP offset due to call frame setup / destroy. 51423322d1427e319089f5098d02cefbc7d8446d746Evan Cheng if (RS) RS->enterBasicBlock(BB); 5150ebe9c132c6b9c74b334f0c7503e702b499575d5Chris Lattner for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) { 5168e3347332120956538a6d882b02719e34b57f0cdEvan Cheng MachineInstr *MI = I; 5178e3347332120956538a6d882b02719e34b57f0cdEvan Cheng 518405abffd5eb1ad1841491e51943b598c935f309bBill Wendling if (I->getOpcode() == TargetInstrInfo::DECLARE) { 519a844bdeab31ef04221e7ef59a8467893584cc14dEvan Cheng // Ignore it. 520988a5782d3ce3cddc65d57d6aac7312d33ed59abBill Wendling ++I; 52171a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner continue; 522405abffd5eb1ad1841491e51943b598c935f309bBill Wendling } 523405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 524405abffd5eb1ad1841491e51943b598c935f309bBill Wendling if (I->getOpcode() == FrameSetupOpcode || 525405abffd5eb1ad1841491e51943b598c935f309bBill Wendling I->getOpcode() == FrameDestroyOpcode) { 526405abffd5eb1ad1841491e51943b598c935f309bBill Wendling // Remember how much SP has been adjusted to create the call 527405abffd5eb1ad1841491e51943b598c935f309bBill Wendling // frame. 52871a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner int Size = I->getOperand(0).getImm(); 529405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 53071a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner if ((!StackGrowsDown && I->getOpcode() == FrameSetupOpcode) || 53171a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner (StackGrowsDown && I->getOpcode() == FrameDestroyOpcode)) 53271a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner Size = -Size; 533988a5782d3ce3cddc65d57d6aac7312d33ed59abBill Wendling 53471a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner SPAdj += Size; 535405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 5365e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner MachineBasicBlock::iterator PrevI = BB->end(); 5375e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner if (I != BB->begin()) PrevI = prior(I); 53871a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner TRI.eliminateCallFramePseudoInstr(Fn, *BB, I); 539405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 54071a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // Visit the instructions created by eliminateCallFramePseudoInstr(). 5415e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner if (PrevI == BB->end()) 5425e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner I = BB->begin(); // The replaced instr was the first in the block. 5435e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner else 5445e6345bde0f3a6405ec1ea852f1e5e5df8642f9cChris Lattner I = next(PrevI); 54571a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner continue; 5468e3347332120956538a6d882b02719e34b57f0cdEvan Cheng } 547988a5782d3ce3cddc65d57d6aac7312d33ed59abBill Wendling 548405abffd5eb1ad1841491e51943b598c935f309bBill Wendling bool DoIncr = true; 549405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 550405abffd5eb1ad1841491e51943b598c935f309bBill Wendling for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) 551d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman if (MI->getOperand(i).isFI()) { 55271a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // Some instructions (e.g. inline asm instructions) can have 55371a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // multiple frame indices and/or cause eliminateFrameIndex 55471a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // to insert more than one instruction. We need the register 55571a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // scavenger to go through all of these instructions so that 55671a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // it can update its register information. We keep the 55771a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // iterator at the point before insertion so that we can 55871a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // revisit them in full. 55971a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner bool AtBeginning = (I == BB->begin()); 56071a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner if (!AtBeginning) --I; 56171a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner 56271a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // If this instruction has a FrameIndex operand, we need to 56371a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // use that target machine register info object to eliminate 56471a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // it. 56571a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner TRI.eliminateFrameIndex(MI, SPAdj, RS); 56671a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner 56771a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner // Reset the iterator if we were at the beginning of the BB. 56871a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner if (AtBeginning) { 56971a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner I = BB->begin(); 57071a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner DoIncr = false; 57171a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner } 57271a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner 57371a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner MI = 0; 57471a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner break; 57571a2cb25ebc818383dd0f80475bc166f834e8d99Chris Lattner } 576405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 577405abffd5eb1ad1841491e51943b598c935f309bBill Wendling if (DoIncr) ++I; 578405abffd5eb1ad1841491e51943b598c935f309bBill Wendling 57949dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng // Update register states. 5800ebe9c132c6b9c74b334f0c7503e702b499575d5Chris Lattner if (RS && MI) RS->forward(MI); 58149dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng } 582988a5782d3ce3cddc65d57d6aac7312d33ed59abBill Wendling 5838e3347332120956538a6d882b02719e34b57f0cdEvan Cheng assert(SPAdj == 0 && "Unbalanced call frame setup / destroy pairs?"); 58449dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng } 58558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner} 586