PrologEpilogInserter.cpp revision a844bdeab31ef04221e7ef59a8467893584cc14d
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" 2758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner#include "llvm/Target/MRegisterInfo.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; 38794fd75c67a2cdc128d67342c6d88a504d186896Devang Patel PEI() : MachineFunctionPass((intptr_t)&ID) {} 39794fd75c67a2cdc128d67342c6d88a504d186896Devang Patel 40f00a3f905e8cd99ab4d3dbbde1a9d510516e0fa2Chris Lattner const char *getPassName() const { 41f00a3f905e8cd99ab4d3dbbde1a9d510516e0fa2Chris Lattner return "Prolog/Epilog Insertion & Frame Finalization"; 4258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 4358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 4458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner /// runOnMachineFunction - Insert prolog/epilog code and replace abstract 4558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner /// frame indexes with appropriate references. 4658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner /// 4758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner bool runOnMachineFunction(MachineFunction &Fn) { 4887f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng const MRegisterInfo *MRI = Fn.getTarget().getRegisterInfo(); 4987f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng RS = MRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : NULL; 5087f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 5144c3b9fdd416c79f4b67cde1aecfced5921efd81Jim Laskey // Get MachineModuleInfo so that we can track the construction of the 524188699f80c233a20b6ddc61570a8a8c1804cb85Jim Laskey // frame. 5384bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner if (MachineModuleInfo *MMI = getAnalysisToUpdate<MachineModuleInfo>()) 5444c3b9fdd416c79f4b67cde1aecfced5921efd81Jim Laskey Fn.getFrameInfo()->setMachineModuleInfo(MMI); 55c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 56c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Allow the target machine to make some adjustments to the function 57c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // e.g. UsedPhysRegs before calculateCalleeSavedRegisters. 5887f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng MRI->processFunctionBeforeCalleeSavedScan(Fn, RS); 59c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 60692d4e0823774730b90e8e2d7bf58119397f0535Evan Cheng // Scan the function for modified callee saved registers and insert spill 61692d4e0823774730b90e8e2d7bf58119397f0535Evan Cheng // code for any callee saved registers that are modified. Also calculate 6258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // the MaxCallFrameSize and HasCalls variables for the function's frame 6358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // information and eliminates call frame pseudo instructions. 64692d4e0823774730b90e8e2d7bf58119397f0535Evan Cheng calculateCalleeSavedRegisters(Fn); 65c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 66c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Add the code to save and restore the callee saved registers 67c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng saveCalleeSavedRegisters(Fn); 6858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 6958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Allow the target machine to make final modifications to the function 7058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // before the frame layout is finalized. 7158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner Fn.getTarget().getRegisterInfo()->processFunctionBeforeFrameFinalized(Fn); 7258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 7358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Calculate actual frame offsets for all of the abstract stack objects... 7458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner calculateFrameObjectOffsets(Fn); 7558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 76c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // Add prolog and epilog code to the function. This function is required 77c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // to align the stack frame as necessary for any stack variables or 78692d4e0823774730b90e8e2d7bf58119397f0535Evan Cheng // called functions. Because of this, calculateCalleeSavedRegisters 79c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // must be called before this function in order to set the HasCalls 80c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // and MaxCallFrameSize variables. 814ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner insertPrologEpilogCode(Fn); 824ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner 8358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Replace all MO_FrameIndex operands with physical register references 8458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // and actual offsets. 8558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // 8658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner replaceFrameIndices(Fn); 87c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 8887f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng delete RS; 8958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner return true; 9058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 91f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey 9258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner private: 9387f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng RegScavenger *RS; 9487f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 95ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng // MinCSFrameIndex, MaxCSFrameIndex - Keeps the range of callee saved 96c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // stack frame indexes. 97c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng unsigned MinCSFrameIndex, MaxCSFrameIndex; 98c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 99692d4e0823774730b90e8e2d7bf58119397f0535Evan Cheng void calculateCalleeSavedRegisters(MachineFunction &Fn); 100c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng void saveCalleeSavedRegisters(MachineFunction &Fn); 10158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner void calculateFrameObjectOffsets(MachineFunction &Fn); 10258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner void replaceFrameIndices(MachineFunction &Fn); 10358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner void insertPrologEpilogCode(MachineFunction &Fn); 10458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner }; 1051997473cf72957d0e70322e2fe6fe2ab141c58a6Devang Patel char PEI::ID = 0; 10658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner} 10758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 108d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 10958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// createPrologEpilogCodeInserter - This function returns a pass that inserts 11058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// prolog and epilog code, and eliminates abstract frame references. 11158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// 11205d8350c12d8d81de1d8af6f7da155bc1c1da50eChris LattnerFunctionPass *llvm::createPrologEpilogCodeInserter() { return new PEI(); } 11358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 11458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 115c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng/// calculateCalleeSavedRegisters - Scan the function for modified callee saved 116c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner/// registers. Also calculate the MaxCallFrameSize and HasCalls variables for 11758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// the function's frame information and eliminates call frame pseudo 11858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// instructions. 11958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// 120692d4e0823774730b90e8e2d7bf58119397f0535Evan Chengvoid PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) { 12158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); 122c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner const TargetFrameInfo *TFI = Fn.getTarget().getFrameInfo(); 12358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 12458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Get the callee saved register list... 1252365f51ed03afe6993bae962fdc2e5a956a64cd5Anton Korobeynikov const unsigned *CSRegs = RegInfo->getCalleeSavedRegs(&Fn); 12658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 12758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Get the function call frame set-up and tear-down instruction opcode 12858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner int FrameSetupOpcode = RegInfo->getCallFrameSetupOpcode(); 12958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner int FrameDestroyOpcode = RegInfo->getCallFrameDestroyOpcode(); 13058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 1317d3223eef2982d7acdfb24facde6605fd9a8b5e8Evan Cheng // These are used to keep track the callee-save area. Initialize them. 1327d3223eef2982d7acdfb24facde6605fd9a8b5e8Evan Cheng MinCSFrameIndex = INT_MAX; 1337d3223eef2982d7acdfb24facde6605fd9a8b5e8Evan Cheng MaxCSFrameIndex = 0; 1347d3223eef2982d7acdfb24facde6605fd9a8b5e8Evan Cheng 13558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Early exit for targets which have no callee saved registers and no call 13658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // frame setup/destroy pseudo instructions. 13758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner if ((CSRegs == 0 || CSRegs[0] == 0) && 13858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner FrameSetupOpcode == -1 && FrameDestroyOpcode == -1) 13958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner return; 14058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 14158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner unsigned MaxCallFrameSize = 0; 14258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner bool HasCalls = false; 14358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 1445c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng std::vector<MachineBasicBlock::iterator> FrameSDOps; 14558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) 1465c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) 147c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos if (I->getOpcode() == FrameSetupOpcode || 148d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner I->getOpcode() == FrameDestroyOpcode) { 1492a82ef317c39ac436f80854c7ddbb06bfddeada1Chris Lattner assert(I->getNumOperands() >= 1 && "Call Frame Setup/Destroy Pseudo" 150d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner " instructions should have a single immediate argument!"); 1519e3304900ff69c4920fea7369c9c36916c4a6a6aChris Lattner unsigned Size = I->getOperand(0).getImm(); 152d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner if (Size > MaxCallFrameSize) MaxCallFrameSize = Size; 153d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner HasCalls = true; 1545c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng FrameSDOps.push_back(I); 15558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 15658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 157eb24db9727a7babe863d5afe70c7bda3a460da18Chris Lattner MachineFrameInfo *FFI = Fn.getFrameInfo(); 15858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner FFI->setHasCalls(HasCalls); 15958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner FFI->setMaxCallFrameSize(MaxCallFrameSize); 1608e3347332120956538a6d882b02719e34b57f0cdEvan Cheng 1615c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng for (unsigned i = 0, e = FrameSDOps.size(); i != e; ++i) { 1625c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng MachineBasicBlock::iterator I = FrameSDOps[i]; 1638e3347332120956538a6d882b02719e34b57f0cdEvan Cheng // If call frames are not being included as part of the stack frame, 1648e3347332120956538a6d882b02719e34b57f0cdEvan Cheng // and there is no dynamic allocation (therefore referencing frame slots 1658e3347332120956538a6d882b02719e34b57f0cdEvan Cheng // off sp), leave the pseudo ops alone. We'll eliminate them later. 1668e3347332120956538a6d882b02719e34b57f0cdEvan Cheng if (RegInfo->hasReservedCallFrame(Fn) || RegInfo->hasFP(Fn)) 1678e3347332120956538a6d882b02719e34b57f0cdEvan Cheng RegInfo->eliminateCallFramePseudoInstr(Fn, *I->getParent(), I); 1685c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng } 16958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 17058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Now figure out which *callee saved* registers are modified by the current 17158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // function, thus needing to be saved and restored in the prolog/epilog. 17258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // 17380a4f169b4a8cd160f832fd4a1052e5d9b2c1a92Chris Lattner const TargetRegisterClass* const *CSRegClasses = 1742365f51ed03afe6993bae962fdc2e5a956a64cd5Anton Korobeynikov RegInfo->getCalleeSavedRegClasses(&Fn); 17508ede262a744f99429658fadb43662441bdcb42dJim Laskey std::vector<CalleeSavedInfo> CSI; 17658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner for (unsigned i = 0; CSRegs[i]; ++i) { 17758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner unsigned Reg = CSRegs[i]; 17884bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner if (Fn.getRegInfo().isPhysRegUsed(Reg)) { 17980a4f169b4a8cd160f832fd4a1052e5d9b2c1a92Chris Lattner // If the reg is modified, save it! 180f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey CSI.push_back(CalleeSavedInfo(Reg, CSRegClasses[i])); 18173ff5120eb8b8c0ccbfed8a17f1024c67a75f319Alkis Evlogimenos } else { 18273ff5120eb8b8c0ccbfed8a17f1024c67a75f319Alkis Evlogimenos for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg); 1833563015b0df358cfc4ec310eb0df195015ea54a5Chris Lattner *AliasSet; ++AliasSet) { // Check alias registers too. 18484bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner if (Fn.getRegInfo().isPhysRegUsed(*AliasSet)) { 185f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey CSI.push_back(CalleeSavedInfo(Reg, CSRegClasses[i])); 186d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner break; 187ecf8afdc2065dec1ca739e2b6a96f8e72dc34533Chris Lattner } 18873ff5120eb8b8c0ccbfed8a17f1024c67a75f319Alkis Evlogimenos } 18973ff5120eb8b8c0ccbfed8a17f1024c67a75f319Alkis Evlogimenos } 19058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 19158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 192f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey if (CSI.empty()) 193c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng return; // Early exit if no callee saved registers are modified! 19458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 195c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner unsigned NumFixedSpillSlots; 1968c9b4de5744ea6c4ce8b79e8a55130df268761cdAlkis Evlogimenos const std::pair<unsigned,int> *FixedSpillSlots = 197ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng TFI->getCalleeSavedSpillSlots(NumFixedSpillSlots); 198c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 19958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Now that we know which registers need to be saved and restored, allocate 20058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // stack slots for them. 201f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 202f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey unsigned Reg = CSI[i].getReg(); 203f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey const TargetRegisterClass *RC = CSI[i].getRegClass(); 204c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 205c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // Check to see if this physreg must be spilled to a particular stack slot 206c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // on this target. 2078c9b4de5744ea6c4ce8b79e8a55130df268761cdAlkis Evlogimenos const std::pair<unsigned,int> *FixedSlot = FixedSpillSlots; 208c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner while (FixedSlot != FixedSpillSlots+NumFixedSpillSlots && 209c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner FixedSlot->first != Reg) 210c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner ++FixedSlot; 211c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 212fa1face30a1943aa17560f6f6e10bb667b257065Chris Lattner int FrameIdx; 213c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner if (FixedSlot == FixedSpillSlots+NumFixedSpillSlots) { 214c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // Nope, just spill it anywhere convenient. 2155feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng unsigned Align = RC->getAlignment(); 2165feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng unsigned StackAlign = TFI->getStackAlignment(); 2175feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng // We may not be able to sastify the desired alignment specification of 2185feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng // the TargetRegisterClass if the stack alignment is smaller. Use the min. 2195feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng Align = std::min(Align, StackAlign); 2205feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng FrameIdx = FFI->CreateStackObject(RC->getSize(), Align); 221c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng if ((unsigned)FrameIdx < MinCSFrameIndex) MinCSFrameIndex = FrameIdx; 222c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng if ((unsigned)FrameIdx > MaxCSFrameIndex) MaxCSFrameIndex = FrameIdx; 223c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner } else { 224c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // Spill it to the stack where we must. 2258fb040e584606f048b85d87363a52baf5ff9c1c7Chris Lattner FrameIdx = FFI->CreateFixedObject(RC->getSize(), FixedSlot->second); 226c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner } 227f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey CSI[i].setFrameIdx(FrameIdx); 22858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 22908ede262a744f99429658fadb43662441bdcb42dJim Laskey 23008ede262a744f99429658fadb43662441bdcb42dJim Laskey FFI->setCalleeSavedInfo(CSI); 231c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner} 232c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 233c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng/// saveCalleeSavedRegisters - Insert spill code for any callee saved registers 234c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner/// that are modified in the function. 235c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner/// 236c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Chengvoid PEI::saveCalleeSavedRegisters(MachineFunction &Fn) { 237f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey // Get callee saved register information. 238f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey MachineFrameInfo *FFI = Fn.getFrameInfo(); 23908ede262a744f99429658fadb43662441bdcb42dJim Laskey const std::vector<CalleeSavedInfo> &CSI = FFI->getCalleeSavedInfo(); 240f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey 241c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Early exit if no callee saved registers are modified! 242f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey if (CSI.empty()) 243edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman return; 244c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 245f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); 24600dff8dda29b5a249cd99405ce26e84cef13ba53Evan Cheng 24758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Now that we have a stack slot for each register to be saved, insert spill 24892b9fcea7b3180ed18f379212d14bd5cea7a1954Chris Lattner // code into the entry block. 24958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner MachineBasicBlock *MBB = Fn.begin(); 25058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner MachineBasicBlock::iterator I = MBB->begin(); 25100dff8dda29b5a249cd99405ce26e84cef13ba53Evan Cheng 252a393cd3306b865e8e5d82dc4e6cfabcdf5d8dc44Owen Anderson if (!TII.spillCalleeSavedRegisters(*MBB, I, CSI)) { 253ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 25449dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng // Add the callee-saved register as live-in. It's killed at the spill. 25549dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng MBB->addLiveIn(CSI[i].getReg()); 25649dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng 257ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng // Insert the spill to the stack frame. 258f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson TII.storeRegToStackSlot(*MBB, I, CSI[i].getReg(), true, 25949dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng CSI[i].getFrameIdx(), CSI[i].getRegClass()); 260ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng } 26158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 26258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 26358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Add code to restore the callee-save registers in each exiting block. 26492b9fcea7b3180ed18f379212d14bd5cea7a1954Chris Lattner for (MachineFunction::iterator FI = Fn.begin(), E = Fn.end(); FI != E; ++FI) 26592b9fcea7b3180ed18f379212d14bd5cea7a1954Chris Lattner // If last instruction is a return instruction, add an epilogue. 266749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner if (!FI->empty() && FI->back().getDesc().isReturn()) { 267c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos MBB = FI; 268c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos I = MBB->end(); --I; 26958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 2704fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner // Skip over all terminator instructions, which are part of the return 2714fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner // sequence. 2724fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner MachineBasicBlock::iterator I2 = I; 273749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner while (I2 != MBB->begin() && (--I2)->getDesc().isTerminator()) 2744fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner I = I2; 2754fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner 276dfd58709cc78e841ef4a50ba75d940473031617eChris Lattner bool AtStart = I == MBB->begin(); 277ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner MachineBasicBlock::iterator BeforeI = I; 278ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner if (!AtStart) 279ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner --BeforeI; 280ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner 2814fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner // Restore all registers immediately before the return and any terminators 2824fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner // that preceed it. 283a393cd3306b865e8e5d82dc4e6cfabcdf5d8dc44Owen Anderson if (!TII.restoreCalleeSavedRegisters(*MBB, I, CSI)) { 284ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 285f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson TII.loadRegFromStackSlot(*MBB, I, CSI[i].getReg(), 286ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng CSI[i].getFrameIdx(), 287ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng CSI[i].getRegClass()); 288ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng assert(I != MBB->begin() && 289ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng "loadRegFromStackSlot didn't insert any code!"); 290ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng // Insert in reverse order. loadRegFromStackSlot can insert multiple 291ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng // instructions. 292ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng if (AtStart) 293ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng I = MBB->begin(); 294ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng else { 295ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng I = BeforeI; 296ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng ++I; 297ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng } 298ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner } 29958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 30058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 30158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner} 30258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 30358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 30458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the 30592b9fcea7b3180ed18f379212d14bd5cea7a1954Chris Lattner/// abstract stack objects. 30658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// 30758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattnervoid PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { 3089bcdcd17c7219dbc68de2f11ca2de86471c8c390Chris Lattner const TargetFrameInfo &TFI = *Fn.getTarget().getFrameInfo(); 309edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 31058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner bool StackGrowsDown = 31158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner TFI.getStackGrowthDirection() == TargetFrameInfo::StackGrowsDown; 312edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 31358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Loop over all of the stack objects, assigning sequential addresses... 314eb24db9727a7babe863d5afe70c7bda3a460da18Chris Lattner MachineFrameInfo *FFI = Fn.getFrameInfo(); 31558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 316cbef8ba5f959b3c4f932005ceef5cf2e0d899f9bChris Lattner unsigned MaxAlign = 0; 31778d6db5627bdf41ab3ffd96133821647dbc60d53Chris Lattner 31805d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner // Start at the beginning of the local area. 319577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // The Offset is the distance from the stack top in the direction 320577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // of stack growth -- so it's always positive. 321a401b1e1c5eb9563617db8a2477b4c5f8b239521Chris Lattner int64_t Offset = TFI.getOffsetOfLocalArea(); 322577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner if (StackGrowsDown) 3237f7bbc2fdb833485ac3d865a405fd948e58e8ddbChris Lattner Offset = -Offset; 324edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman assert(Offset >= 0 325577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner && "Local area offset should be in direction of stack growth"); 326577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner 327577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // If there are fixed sized objects that are preallocated in the local area, 328577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // non-fixed objects can't be allocated right at the start of local area. 329edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman // We currently don't support filling in holes in between fixed sized objects, 330577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // so we adjust 'Offset' to point to the end of last fixed sized 33105d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner // preallocated object. 33205d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) { 333a401b1e1c5eb9563617db8a2477b4c5f8b239521Chris Lattner int64_t FixedOff; 334577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner if (StackGrowsDown) { 335577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // The maximum distance from the stack pointer is at lower address of 336577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // the object -- which is given by offset. For down growing stack 337577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // the offset is negative, so we negate the offset to get the distance. 338577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner FixedOff = -FFI->getObjectOffset(i); 339577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner } else { 340edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman // The maximum distance from the start pointer is at the upper 341577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // address of the object. 342577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner FixedOff = FFI->getObjectOffset(i) + FFI->getObjectSize(i); 343edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman } 344edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman if (FixedOff > Offset) Offset = FixedOff; 34505d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner } 34605d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner 347c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // First assign frame offsets to stack objects that are used to spill 348ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng // callee saved registers. 349c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng if (StackGrowsDown) { 3505c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng for (unsigned i = MinCSFrameIndex; i <= MaxCSFrameIndex; ++i) { 351c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // If stack grows down, we need to add size of find the lowest 352c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // address of the object. 353c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng Offset += FFI->getObjectSize(i); 354c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 355c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng unsigned Align = FFI->getObjectAlignment(i); 356c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // If the alignment of this object is greater than that of the stack, then 357c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // increase the stack alignment to match. 358c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng MaxAlign = std::max(MaxAlign, Align); 359c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Adjust to alignment boundary 360c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng Offset = (Offset+Align-1)/Align*Align; 361c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 362c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng FFI->setObjectOffset(i, -Offset); // Set the computed offset 363c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng } 364c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng } else { 3655c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng for (unsigned i = MaxCSFrameIndex; i >= MinCSFrameIndex; --i) { 366c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng unsigned Align = FFI->getObjectAlignment(i); 367c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // If the alignment of this object is greater than that of the stack, then 368c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // increase the stack alignment to match. 369c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng MaxAlign = std::max(MaxAlign, Align); 370c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Adjust to alignment boundary 371c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng Offset = (Offset+Align-1)/Align*Align; 372c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 373c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng FFI->setObjectOffset(i, Offset); 374c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng Offset += FFI->getObjectSize(i); 375c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng } 376c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng } 377c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 37887f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // Make sure the special register scavenging spill slot is closest to the 37987f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // frame pointer if a frame pointer is required. 38087f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); 38187f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng if (RS && RegInfo->hasFP(Fn)) { 38287f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng int SFI = RS->getScavengingFrameIndex(); 38387f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng if (SFI >= 0) { 3845c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng // If stack grows down, we need to add size of the lowest 38587f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // address of the object. 38687f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng if (StackGrowsDown) 38787f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng Offset += FFI->getObjectSize(SFI); 38887f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 38987f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng unsigned Align = FFI->getObjectAlignment(SFI); 39087f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // Adjust to alignment boundary 39187f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng Offset = (Offset+Align-1)/Align*Align; 39287f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 39387f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng if (StackGrowsDown) { 39487f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng FFI->setObjectOffset(SFI, -Offset); // Set the computed offset 39587f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng } else { 39687f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng FFI->setObjectOffset(SFI, Offset); 39787f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng Offset += FFI->getObjectSize(SFI); 39887f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng } 39987f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng } 40087f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng } 40187f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 402c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Then assign frame offsets to stack objects that are not used to spill 403ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng // callee saved registers. 40458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) { 405c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex) 406c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng continue; 40787f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng if (RS && (int)i == RS->getScavengingFrameIndex()) 40887f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng continue; 409c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 410577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // If stack grows down, we need to add size of find the lowest 411577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // address of the object. 412577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner if (StackGrowsDown) 413577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner Offset += FFI->getObjectSize(i); 41458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 41558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner unsigned Align = FFI->getObjectAlignment(i); 416ae232e7a1055033436370c0b3aecf054fa44d5e7Nate Begeman // If the alignment of this object is greater than that of the stack, then 417ae232e7a1055033436370c0b3aecf054fa44d5e7Nate Begeman // increase the stack alignment to match. 418ae232e7a1055033436370c0b3aecf054fa44d5e7Nate Begeman MaxAlign = std::max(MaxAlign, Align); 419ae232e7a1055033436370c0b3aecf054fa44d5e7Nate Begeman // Adjust to alignment boundary 420ae232e7a1055033436370c0b3aecf054fa44d5e7Nate Begeman Offset = (Offset+Align-1)/Align*Align; 421edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 422577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner if (StackGrowsDown) { 423577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner FFI->setObjectOffset(i, -Offset); // Set the computed offset 424577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner } else { 425edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman FFI->setObjectOffset(i, Offset); 426577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner Offset += FFI->getObjectSize(i); 427577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner } 42858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 42958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 43087f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // Make sure the special register scavenging spill slot is closest to the 43187f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // stack pointer. 4328d410b69384ae4e178b3b522ef3357290a714de5Lauro Ramos Venancio if (RS && !RegInfo->hasFP(Fn)) { 43387f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng int SFI = RS->getScavengingFrameIndex(); 43487f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng if (SFI >= 0) { 43587f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // If stack grows down, we need to add size of find the lowest 43687f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // address of the object. 43787f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng if (StackGrowsDown) 43887f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng Offset += FFI->getObjectSize(SFI); 43987f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 44087f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng unsigned Align = FFI->getObjectAlignment(SFI); 44187f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // Adjust to alignment boundary 44287f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng Offset = (Offset+Align-1)/Align*Align; 44387f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 44487f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng if (StackGrowsDown) { 44587f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng FFI->setObjectOffset(SFI, -Offset); // Set the computed offset 44687f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng } else { 44787f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng FFI->setObjectOffset(SFI, Offset); 44887f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng Offset += FFI->getObjectSize(SFI); 44987f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng } 45087f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng } 45187f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng } 45287f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 453367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng // Round up the size to a multiple of the alignment, but only if there are 454367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng // calls or alloca's in the function. This ensures that any calls to 455367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng // subroutines have their stack frames suitable aligned. 45602a20291410a6814c657b69901a57103d4861a07Evan Cheng if (!RegInfo->targetHandlesStackFrameRounding() && 45702a20291410a6814c657b69901a57103d4861a07Evan Cheng (FFI->hasCalls() || FFI->hasVarSizedObjects())) { 4585c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng // If we have reserved argument space for call sites in the function 4595c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng // immediately on entry to the current function, count it as part of the 4605c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng // overall stack size. 4615c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng if (RegInfo->hasReservedCallFrame(Fn)) 462367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng Offset += FFI->getMaxCallFrameSize(); 463367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng 464367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng unsigned AlignMask = TFI.getStackAlignment() - 1; 465ea84c5ee952c62dd0c703c9852d7a60715e4a435Chris Lattner Offset = (Offset + AlignMask) & ~uint64_t(AlignMask); 466367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng } 467367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng 468367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng // Update frame info to pretend that this is part of the stack... 4697f7bbc2fdb833485ac3d865a405fd948e58e8ddbChris Lattner FFI->setStackSize(Offset+TFI.getOffsetOfLocalArea()); 470cbef8ba5f959b3c4f932005ceef5cf2e0d899f9bChris Lattner 471cbef8ba5f959b3c4f932005ceef5cf2e0d899f9bChris Lattner // Remember the required stack alignment in case targets need it to perform 472cbef8ba5f959b3c4f932005ceef5cf2e0d899f9bChris Lattner // dynamic stack alignment. 4734672f71ac4d056aa22d6b09838a3eb22a2e384e7Chris Lattner assert(FFI->getMaxAlignment() == MaxAlign && 4744672f71ac4d056aa22d6b09838a3eb22a2e384e7Chris Lattner "Stack alignment calculation broken!"); 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) { 4834ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner // Add prologue to the function... 4844ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner Fn.getTarget().getRegisterInfo()->emitPrologue(Fn); 4854ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner 4864ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner // Add epilogue to restore the callee-save registers in each exiting block 4874ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) { 4884ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner // If last instruction is a return instruction, add an epilogue 489749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner if (!I->empty() && I->back().getDesc().isReturn()) 4904ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner Fn.getTarget().getRegisterInfo()->emitEpilogue(Fn, *I); 4914ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner } 49258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner} 49358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 49458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 49558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// replaceFrameIndices - Replace all MO_FrameIndex operands with physical 49658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// register references and actual offsets. 49758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// 49858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattnervoid PEI::replaceFrameIndices(MachineFunction &Fn) { 49958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner if (!Fn.getFrameInfo()->hasStackObjects()) return; // Nothing to do? 50058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 50158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner const TargetMachine &TM = Fn.getTarget(); 50258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner assert(TM.getRegisterInfo() && "TM::getRegisterInfo() must be implemented!"); 50358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner const MRegisterInfo &MRI = *TM.getRegisterInfo(); 5048e3347332120956538a6d882b02719e34b57f0cdEvan Cheng const TargetFrameInfo *TFI = TM.getFrameInfo(); 5058e3347332120956538a6d882b02719e34b57f0cdEvan Cheng bool StackGrowsDown = 5068e3347332120956538a6d882b02719e34b57f0cdEvan Cheng TFI->getStackGrowthDirection() == TargetFrameInfo::StackGrowsDown; 5078e3347332120956538a6d882b02719e34b57f0cdEvan Cheng int FrameSetupOpcode = MRI.getCallFrameSetupOpcode(); 5088e3347332120956538a6d882b02719e34b57f0cdEvan Cheng int FrameDestroyOpcode = MRI.getCallFrameDestroyOpcode(); 50958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 51049dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) { 5118e3347332120956538a6d882b02719e34b57f0cdEvan Cheng int SPAdj = 0; // SP offset due to call frame setup / destroy. 51223322d1427e319089f5098d02cefbc7d8446d746Evan Cheng if (RS) RS->enterBasicBlock(BB); 5130ebe9c132c6b9c74b334f0c7503e702b499575d5Chris Lattner for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) { 5148e3347332120956538a6d882b02719e34b57f0cdEvan Cheng MachineInstr *MI = I; 5158e3347332120956538a6d882b02719e34b57f0cdEvan Cheng 5168e3347332120956538a6d882b02719e34b57f0cdEvan Cheng if (I->getOpcode() == FrameSetupOpcode || 5178e3347332120956538a6d882b02719e34b57f0cdEvan Cheng I->getOpcode() == FrameDestroyOpcode) { 518a844bdeab31ef04221e7ef59a8467893584cc14dEvan Cheng // Remember how much SP has been adjustment to create the call frame. 5199e3304900ff69c4920fea7369c9c36916c4a6a6aChris Lattner int Size = I->getOperand(0).getImm(); 5208e3347332120956538a6d882b02719e34b57f0cdEvan Cheng if ((!StackGrowsDown && I->getOpcode() == FrameSetupOpcode) || 5218e3347332120956538a6d882b02719e34b57f0cdEvan Cheng (StackGrowsDown && I->getOpcode() == FrameDestroyOpcode)) 5228e3347332120956538a6d882b02719e34b57f0cdEvan Cheng Size = -Size; 5238e3347332120956538a6d882b02719e34b57f0cdEvan Cheng SPAdj += Size; 5248e3347332120956538a6d882b02719e34b57f0cdEvan Cheng MachineBasicBlock::iterator PrevI = prior(I); 5258e3347332120956538a6d882b02719e34b57f0cdEvan Cheng MRI.eliminateCallFramePseudoInstr(Fn, *BB, I); 5268e3347332120956538a6d882b02719e34b57f0cdEvan Cheng // Visit the instructions created by eliminateCallFramePseudoInstr(). 5278e3347332120956538a6d882b02719e34b57f0cdEvan Cheng I = next(PrevI); 5288e3347332120956538a6d882b02719e34b57f0cdEvan Cheng MI = NULL; 529a844bdeab31ef04221e7ef59a8467893584cc14dEvan Cheng } else if (I->getOpcode() == TargetInstrInfo::DECLARE) 530a844bdeab31ef04221e7ef59a8467893584cc14dEvan Cheng // Ignore it. 531a844bdeab31ef04221e7ef59a8467893584cc14dEvan Cheng I++; 532a844bdeab31ef04221e7ef59a8467893584cc14dEvan Cheng else { 5338e3347332120956538a6d882b02719e34b57f0cdEvan Cheng I++; 5348e3347332120956538a6d882b02719e34b57f0cdEvan Cheng for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) 5358e3347332120956538a6d882b02719e34b57f0cdEvan Cheng if (MI->getOperand(i).isFrameIndex()) { 5368e3347332120956538a6d882b02719e34b57f0cdEvan Cheng // If this instruction has a FrameIndex operand, we need to use that 5378e3347332120956538a6d882b02719e34b57f0cdEvan Cheng // target machine register info object to eliminate it. 5388e3347332120956538a6d882b02719e34b57f0cdEvan Cheng MRI.eliminateFrameIndex(MI, SPAdj, RS); 5398e3347332120956538a6d882b02719e34b57f0cdEvan Cheng 5408e3347332120956538a6d882b02719e34b57f0cdEvan Cheng // Revisit the instruction in full. Some instructions (e.g. inline 5418e3347332120956538a6d882b02719e34b57f0cdEvan Cheng // asm instructions) can have multiple frame indices. 5428e3347332120956538a6d882b02719e34b57f0cdEvan Cheng --I; 5438e3347332120956538a6d882b02719e34b57f0cdEvan Cheng MI = 0; 5448e3347332120956538a6d882b02719e34b57f0cdEvan Cheng break; 5458e3347332120956538a6d882b02719e34b57f0cdEvan Cheng } 5468e3347332120956538a6d882b02719e34b57f0cdEvan Cheng } 54749dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng // Update register states. 5480ebe9c132c6b9c74b334f0c7503e702b499575d5Chris Lattner if (RS && MI) RS->forward(MI); 54949dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng } 5508e3347332120956538a6d882b02719e34b57f0cdEvan Cheng assert(SPAdj == 0 && "Unbalanced call frame setup / destroy pairs?"); 55149dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng } 55258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner} 553