PrologEpilogInserter.cpp revision 1997473cf72957d0e70322e2fe6fe2ab141c58a6
158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner//===-- PrologEpilogInserter.cpp - Insert Prolog/Epilog code in function --===// 2edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman// 3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// The LLVM Compiler Infrastructure 4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// 5b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// This file was developed by the LLVM research group and is distributed under 6b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// the University of Illinois Open Source 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" 2349dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng#include "llvm/CodeGen/RegisterScavenging.h" 2458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner#include "llvm/Target/TargetMachine.h" 2558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner#include "llvm/Target/MRegisterInfo.h" 268bd66e690779c838db51f55cf0b31d7206b3b659Chris Lattner#include "llvm/Target/TargetFrameInfo.h" 273501feab811c86c9659248a4875fc31a3165f84dChris Lattner#include "llvm/Target/TargetInstrInfo.h" 28a4f0b3a084d120cfc5b5bb06f64b222f5cb72740Chris Lattner#include "llvm/Support/Compiler.h" 298e3347332120956538a6d882b02719e34b57f0cdEvan Cheng#include "llvm/ADT/STLExtras.h" 30c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng#include <climits> 3105d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattnerusing namespace llvm; 32d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 3358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattnernamespace { 34f8c68f694c25b1ae8c0e5adb2a19432cb405d232Chris Lattner struct VISIBILITY_HIDDEN PEI : public MachineFunctionPass { 351997473cf72957d0e70322e2fe6fe2ab141c58a6Devang Patel static char ID; 36794fd75c67a2cdc128d67342c6d88a504d186896Devang Patel PEI() : MachineFunctionPass((intptr_t)&ID) {} 37794fd75c67a2cdc128d67342c6d88a504d186896Devang Patel 38f00a3f905e8cd99ab4d3dbbde1a9d510516e0fa2Chris Lattner const char *getPassName() const { 39f00a3f905e8cd99ab4d3dbbde1a9d510516e0fa2Chris Lattner return "Prolog/Epilog Insertion & Frame Finalization"; 4058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 4158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 4258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner /// runOnMachineFunction - Insert prolog/epilog code and replace abstract 4358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner /// frame indexes with appropriate references. 4458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner /// 4558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner bool runOnMachineFunction(MachineFunction &Fn) { 4687f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng const MRegisterInfo *MRI = Fn.getTarget().getRegisterInfo(); 4787f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng RS = MRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : NULL; 4887f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 4944c3b9fdd416c79f4b67cde1aecfced5921efd81Jim Laskey // Get MachineModuleInfo so that we can track the construction of the 504188699f80c233a20b6ddc61570a8a8c1804cb85Jim Laskey // frame. 5144c3b9fdd416c79f4b67cde1aecfced5921efd81Jim Laskey if (MachineModuleInfo *MMI = getAnalysisToUpdate<MachineModuleInfo>()) { 5244c3b9fdd416c79f4b67cde1aecfced5921efd81Jim Laskey Fn.getFrameInfo()->setMachineModuleInfo(MMI); 534188699f80c233a20b6ddc61570a8a8c1804cb85Jim Laskey } 54c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 55c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Allow the target machine to make some adjustments to the function 56c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // e.g. UsedPhysRegs before calculateCalleeSavedRegisters. 5787f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng MRI->processFunctionBeforeCalleeSavedScan(Fn, RS); 58c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 59692d4e0823774730b90e8e2d7bf58119397f0535Evan Cheng // Scan the function for modified callee saved registers and insert spill 60692d4e0823774730b90e8e2d7bf58119397f0535Evan Cheng // code for any callee saved registers that are modified. Also calculate 6158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // the MaxCallFrameSize and HasCalls variables for the function's frame 6258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // information and eliminates call frame pseudo instructions. 63692d4e0823774730b90e8e2d7bf58119397f0535Evan Cheng calculateCalleeSavedRegisters(Fn); 64c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 65c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Add the code to save and restore the callee saved registers 66c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng saveCalleeSavedRegisters(Fn); 6758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 6858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Allow the target machine to make final modifications to the function 6958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // before the frame layout is finalized. 7058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner Fn.getTarget().getRegisterInfo()->processFunctionBeforeFrameFinalized(Fn); 7158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 7258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Calculate actual frame offsets for all of the abstract stack objects... 7358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner calculateFrameObjectOffsets(Fn); 7458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 75c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // Add prolog and epilog code to the function. This function is required 76c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // to align the stack frame as necessary for any stack variables or 77692d4e0823774730b90e8e2d7bf58119397f0535Evan Cheng // called functions. Because of this, calculateCalleeSavedRegisters 78c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // must be called before this function in order to set the HasCalls 79c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // and MaxCallFrameSize variables. 804ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner insertPrologEpilogCode(Fn); 814ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner 8258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Replace all MO_FrameIndex operands with physical register references 8358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // and actual offsets. 8458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // 8558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner replaceFrameIndices(Fn); 86c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 8787f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng delete RS; 8858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner return true; 8958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 90f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey 9158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner private: 9287f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng RegScavenger *RS; 9387f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 94ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng // MinCSFrameIndex, MaxCSFrameIndex - Keeps the range of callee saved 95c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // stack frame indexes. 96c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng unsigned MinCSFrameIndex, MaxCSFrameIndex; 97c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 98692d4e0823774730b90e8e2d7bf58119397f0535Evan Cheng void calculateCalleeSavedRegisters(MachineFunction &Fn); 99c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng void saveCalleeSavedRegisters(MachineFunction &Fn); 10058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner void calculateFrameObjectOffsets(MachineFunction &Fn); 10158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner void replaceFrameIndices(MachineFunction &Fn); 10258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner void insertPrologEpilogCode(MachineFunction &Fn); 10358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner }; 1041997473cf72957d0e70322e2fe6fe2ab141c58a6Devang Patel char PEI::ID = 0; 10558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner} 10658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 107d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 10858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// createPrologEpilogCodeInserter - This function returns a pass that inserts 10958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// prolog and epilog code, and eliminates abstract frame references. 11058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// 11105d8350c12d8d81de1d8af6f7da155bc1c1da50eChris LattnerFunctionPass *llvm::createPrologEpilogCodeInserter() { return new PEI(); } 11258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 11358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 114c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng/// calculateCalleeSavedRegisters - Scan the function for modified callee saved 115c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner/// registers. Also calculate the MaxCallFrameSize and HasCalls variables for 11658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// the function's frame information and eliminates call frame pseudo 11758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// instructions. 11858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// 119692d4e0823774730b90e8e2d7bf58119397f0535Evan Chengvoid PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) { 12058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); 121c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner const TargetFrameInfo *TFI = Fn.getTarget().getFrameInfo(); 12258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 12358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Get the callee saved register list... 124ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng const unsigned *CSRegs = RegInfo->getCalleeSavedRegs(); 12558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 12658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Get the function call frame set-up and tear-down instruction opcode 12758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner int FrameSetupOpcode = RegInfo->getCallFrameSetupOpcode(); 12858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner int FrameDestroyOpcode = RegInfo->getCallFrameDestroyOpcode(); 12958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 1307d3223eef2982d7acdfb24facde6605fd9a8b5e8Evan Cheng // These are used to keep track the callee-save area. Initialize them. 1317d3223eef2982d7acdfb24facde6605fd9a8b5e8Evan Cheng MinCSFrameIndex = INT_MAX; 1327d3223eef2982d7acdfb24facde6605fd9a8b5e8Evan Cheng MaxCSFrameIndex = 0; 1337d3223eef2982d7acdfb24facde6605fd9a8b5e8Evan Cheng 13458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Early exit for targets which have no callee saved registers and no call 13558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // frame setup/destroy pseudo instructions. 13658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner if ((CSRegs == 0 || CSRegs[0] == 0) && 13758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner FrameSetupOpcode == -1 && FrameDestroyOpcode == -1) 13858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner return; 13958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 14058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner unsigned MaxCallFrameSize = 0; 14158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner bool HasCalls = false; 14258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 1435c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng std::vector<MachineBasicBlock::iterator> FrameSDOps; 14458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) 1455c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) 146c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos if (I->getOpcode() == FrameSetupOpcode || 147d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner I->getOpcode() == FrameDestroyOpcode) { 1482a82ef317c39ac436f80854c7ddbb06bfddeada1Chris Lattner assert(I->getNumOperands() >= 1 && "Call Frame Setup/Destroy Pseudo" 149d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner " instructions should have a single immediate argument!"); 150d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner unsigned Size = I->getOperand(0).getImmedValue(); 151d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner if (Size > MaxCallFrameSize) MaxCallFrameSize = Size; 152d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner HasCalls = true; 1535c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng FrameSDOps.push_back(I); 15458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 15558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 156eb24db9727a7babe863d5afe70c7bda3a460da18Chris Lattner MachineFrameInfo *FFI = Fn.getFrameInfo(); 15758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner FFI->setHasCalls(HasCalls); 15858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner FFI->setMaxCallFrameSize(MaxCallFrameSize); 1598e3347332120956538a6d882b02719e34b57f0cdEvan Cheng 1605c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng for (unsigned i = 0, e = FrameSDOps.size(); i != e; ++i) { 1615c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng MachineBasicBlock::iterator I = FrameSDOps[i]; 1628e3347332120956538a6d882b02719e34b57f0cdEvan Cheng // If call frames are not being included as part of the stack frame, 1638e3347332120956538a6d882b02719e34b57f0cdEvan Cheng // and there is no dynamic allocation (therefore referencing frame slots 1648e3347332120956538a6d882b02719e34b57f0cdEvan Cheng // off sp), leave the pseudo ops alone. We'll eliminate them later. 1658e3347332120956538a6d882b02719e34b57f0cdEvan Cheng if (RegInfo->hasReservedCallFrame(Fn) || RegInfo->hasFP(Fn)) 1668e3347332120956538a6d882b02719e34b57f0cdEvan Cheng RegInfo->eliminateCallFramePseudoInstr(Fn, *I->getParent(), I); 1675c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng } 16858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 16958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Now figure out which *callee saved* registers are modified by the current 17058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // function, thus needing to be saved and restored in the prolog/epilog. 17158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // 17280a4f169b4a8cd160f832fd4a1052e5d9b2c1a92Chris Lattner const TargetRegisterClass* const *CSRegClasses = 173ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng RegInfo->getCalleeSavedRegClasses(); 17408ede262a744f99429658fadb43662441bdcb42dJim Laskey std::vector<CalleeSavedInfo> CSI; 17558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner for (unsigned i = 0; CSRegs[i]; ++i) { 17658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner unsigned Reg = CSRegs[i]; 1776c087e5585b227f3c1d8278304c7cfbc7cd4f6e8Evan Cheng if (Fn.isPhysRegUsed(Reg)) { 17880a4f169b4a8cd160f832fd4a1052e5d9b2c1a92Chris Lattner // If the reg is modified, save it! 179f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey CSI.push_back(CalleeSavedInfo(Reg, CSRegClasses[i])); 18073ff5120eb8b8c0ccbfed8a17f1024c67a75f319Alkis Evlogimenos } else { 18173ff5120eb8b8c0ccbfed8a17f1024c67a75f319Alkis Evlogimenos for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg); 1823563015b0df358cfc4ec310eb0df195015ea54a5Chris Lattner *AliasSet; ++AliasSet) { // Check alias registers too. 1836c087e5585b227f3c1d8278304c7cfbc7cd4f6e8Evan Cheng if (Fn.isPhysRegUsed(*AliasSet)) { 184f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey CSI.push_back(CalleeSavedInfo(Reg, CSRegClasses[i])); 185d555da52f4301f0a221845d5a549848f5ae84577Chris Lattner break; 186ecf8afdc2065dec1ca739e2b6a96f8e72dc34533Chris Lattner } 18773ff5120eb8b8c0ccbfed8a17f1024c67a75f319Alkis Evlogimenos } 18873ff5120eb8b8c0ccbfed8a17f1024c67a75f319Alkis Evlogimenos } 18958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 19058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 191f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey if (CSI.empty()) 192c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng return; // Early exit if no callee saved registers are modified! 19358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 194c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner unsigned NumFixedSpillSlots; 1958c9b4de5744ea6c4ce8b79e8a55130df268761cdAlkis Evlogimenos const std::pair<unsigned,int> *FixedSpillSlots = 196ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng TFI->getCalleeSavedSpillSlots(NumFixedSpillSlots); 197c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 19858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Now that we know which registers need to be saved and restored, allocate 19958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // stack slots for them. 200f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 201f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey unsigned Reg = CSI[i].getReg(); 202f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey const TargetRegisterClass *RC = CSI[i].getRegClass(); 203c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 204c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // Check to see if this physreg must be spilled to a particular stack slot 205c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // on this target. 2068c9b4de5744ea6c4ce8b79e8a55130df268761cdAlkis Evlogimenos const std::pair<unsigned,int> *FixedSlot = FixedSpillSlots; 207c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner while (FixedSlot != FixedSpillSlots+NumFixedSpillSlots && 208c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner FixedSlot->first != Reg) 209c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner ++FixedSlot; 210c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 211fa1face30a1943aa17560f6f6e10bb667b257065Chris Lattner int FrameIdx; 212c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner if (FixedSlot == FixedSpillSlots+NumFixedSpillSlots) { 213c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // Nope, just spill it anywhere convenient. 2145feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng unsigned Align = RC->getAlignment(); 2155feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng unsigned StackAlign = TFI->getStackAlignment(); 2165feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng // We may not be able to sastify the desired alignment specification of 2175feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng // the TargetRegisterClass if the stack alignment is smaller. Use the min. 2185feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng Align = std::min(Align, StackAlign); 2195feaa9a70716e9181a9b940236bc461f2a75334aEvan Cheng FrameIdx = FFI->CreateStackObject(RC->getSize(), Align); 220c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng if ((unsigned)FrameIdx < MinCSFrameIndex) MinCSFrameIndex = FrameIdx; 221c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng if ((unsigned)FrameIdx > MaxCSFrameIndex) MaxCSFrameIndex = FrameIdx; 222c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner } else { 223c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner // Spill it to the stack where we must. 2248fb040e584606f048b85d87363a52baf5ff9c1c7Chris Lattner FrameIdx = FFI->CreateFixedObject(RC->getSize(), FixedSlot->second); 225c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner } 226f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey CSI[i].setFrameIdx(FrameIdx); 22758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 22808ede262a744f99429658fadb43662441bdcb42dJim Laskey 22908ede262a744f99429658fadb43662441bdcb42dJim Laskey FFI->setCalleeSavedInfo(CSI); 230c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner} 231c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 232c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng/// saveCalleeSavedRegisters - Insert spill code for any callee saved registers 233c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner/// that are modified in the function. 234c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner/// 235c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Chengvoid PEI::saveCalleeSavedRegisters(MachineFunction &Fn) { 236f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey // Get callee saved register information. 237f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey MachineFrameInfo *FFI = Fn.getFrameInfo(); 23808ede262a744f99429658fadb43662441bdcb42dJim Laskey const std::vector<CalleeSavedInfo> &CSI = FFI->getCalleeSavedInfo(); 239f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey 240c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Early exit if no callee saved registers are modified! 241f3e4f0e615bb2c36c4a9d60bb908e08b76025c75Jim Laskey if (CSI.empty()) 242edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman return; 243c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner 244c330b68fb7f1cb7f05a60ab4d811bba397538840Chris Lattner const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); 24558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 24658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Now that we have a stack slot for each register to be saved, insert spill 24792b9fcea7b3180ed18f379212d14bd5cea7a1954Chris Lattner // code into the entry block. 24858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner MachineBasicBlock *MBB = Fn.begin(); 24958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner MachineBasicBlock::iterator I = MBB->begin(); 250ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng if (!RegInfo->spillCalleeSavedRegisters(*MBB, I, CSI)) { 251ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 25249dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng // Add the callee-saved register as live-in. It's killed at the spill. 25349dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng MBB->addLiveIn(CSI[i].getReg()); 25449dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng 255ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng // Insert the spill to the stack frame. 256ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng RegInfo->storeRegToStackSlot(*MBB, I, CSI[i].getReg(), 25749dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng CSI[i].getFrameIdx(), CSI[i].getRegClass()); 258ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng } 25958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 26058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 26158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Add code to restore the callee-save registers in each exiting block. 2629bcdcd17c7219dbc68de2f11ca2de86471c8c390Chris Lattner const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); 26392b9fcea7b3180ed18f379212d14bd5cea7a1954Chris Lattner for (MachineFunction::iterator FI = Fn.begin(), E = Fn.end(); FI != E; ++FI) 26492b9fcea7b3180ed18f379212d14bd5cea7a1954Chris Lattner // If last instruction is a return instruction, add an epilogue. 265c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos if (!FI->empty() && TII.isReturn(FI->back().getOpcode())) { 266c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos MBB = FI; 267c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos I = MBB->end(); --I; 26858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 2694fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner // Skip over all terminator instructions, which are part of the return 2704fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner // sequence. 2714fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner MachineBasicBlock::iterator I2 = I; 2724fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner while (I2 != MBB->begin() && TII.isTerminatorInstr((--I2)->getOpcode())) 2734fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner I = I2; 2744fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner 275dfd58709cc78e841ef4a50ba75d940473031617eChris Lattner bool AtStart = I == MBB->begin(); 276ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner MachineBasicBlock::iterator BeforeI = I; 277ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner if (!AtStart) 278ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner --BeforeI; 279ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner 2804fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner // Restore all registers immediately before the return and any terminators 2814fc997941dde5c11e91a28c9b5b8fa331d053a18Chris Lattner // that preceed it. 282ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng if (!RegInfo->restoreCalleeSavedRegisters(*MBB, I, CSI)) { 283ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 284ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng RegInfo->loadRegFromStackSlot(*MBB, I, CSI[i].getReg(), 285ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng CSI[i].getFrameIdx(), 286ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng CSI[i].getRegClass()); 287ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng assert(I != MBB->begin() && 288ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng "loadRegFromStackSlot didn't insert any code!"); 289ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng // Insert in reverse order. loadRegFromStackSlot can insert multiple 290ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng // instructions. 291ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng if (AtStart) 292ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng I = MBB->begin(); 293ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng else { 294ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng I = BeforeI; 295ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng ++I; 296ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng } 297ed461e0fafbd0b905cb716df108000bcd6ecf3d4Chris Lattner } 29858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 29958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 30058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner} 30158b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 30258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 30358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the 30492b9fcea7b3180ed18f379212d14bd5cea7a1954Chris Lattner/// abstract stack objects. 30558b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner/// 30658b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattnervoid PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { 3079bcdcd17c7219dbc68de2f11ca2de86471c8c390Chris Lattner const TargetFrameInfo &TFI = *Fn.getTarget().getFrameInfo(); 308edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 30958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner bool StackGrowsDown = 31058b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner TFI.getStackGrowthDirection() == TargetFrameInfo::StackGrowsDown; 311edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 31258b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner // Loop over all of the stack objects, assigning sequential addresses... 313eb24db9727a7babe863d5afe70c7bda3a460da18Chris Lattner MachineFrameInfo *FFI = Fn.getFrameInfo(); 31458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 315cbef8ba5f959b3c4f932005ceef5cf2e0d899f9bChris Lattner unsigned MaxAlign = 0; 31678d6db5627bdf41ab3ffd96133821647dbc60d53Chris Lattner 31705d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner // Start at the beginning of the local area. 318577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // The Offset is the distance from the stack top in the direction 319577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // of stack growth -- so it's always positive. 320a401b1e1c5eb9563617db8a2477b4c5f8b239521Chris Lattner int64_t Offset = TFI.getOffsetOfLocalArea(); 321577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner if (StackGrowsDown) 3227f7bbc2fdb833485ac3d865a405fd948e58e8ddbChris Lattner Offset = -Offset; 323edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman assert(Offset >= 0 324577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner && "Local area offset should be in direction of stack growth"); 325577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner 326577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // If there are fixed sized objects that are preallocated in the local area, 327577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // non-fixed objects can't be allocated right at the start of local area. 328edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman // We currently don't support filling in holes in between fixed sized objects, 329577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // so we adjust 'Offset' to point to the end of last fixed sized 33005d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner // preallocated object. 33105d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) { 332a401b1e1c5eb9563617db8a2477b4c5f8b239521Chris Lattner int64_t FixedOff; 333577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner if (StackGrowsDown) { 334577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // The maximum distance from the stack pointer is at lower address of 335577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // the object -- which is given by offset. For down growing stack 336577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // the offset is negative, so we negate the offset to get the distance. 337577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner FixedOff = -FFI->getObjectOffset(i); 338577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner } else { 339edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman // The maximum distance from the start pointer is at the upper 340577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // address of the object. 341577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner FixedOff = FFI->getObjectOffset(i) + FFI->getObjectSize(i); 342edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman } 343edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman if (FixedOff > Offset) Offset = FixedOff; 34405d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner } 34505d8350c12d8d81de1d8af6f7da155bc1c1da50eChris Lattner 346c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // First assign frame offsets to stack objects that are used to spill 347ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng // callee saved registers. 348c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng if (StackGrowsDown) { 3495c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng for (unsigned i = MinCSFrameIndex; i <= MaxCSFrameIndex; ++i) { 350c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // If stack grows down, we need to add size of find the lowest 351c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // address of the object. 352c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng Offset += FFI->getObjectSize(i); 353c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 354c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng unsigned Align = FFI->getObjectAlignment(i); 355c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // If the alignment of this object is greater than that of the stack, then 356c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // increase the stack alignment to match. 357c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng MaxAlign = std::max(MaxAlign, Align); 358c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Adjust to alignment boundary 359c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng Offset = (Offset+Align-1)/Align*Align; 360c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 361c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng FFI->setObjectOffset(i, -Offset); // Set the computed offset 362c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng } 363c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng } else { 3645c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng for (unsigned i = MaxCSFrameIndex; i >= MinCSFrameIndex; --i) { 365c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng unsigned Align = FFI->getObjectAlignment(i); 366c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // If the alignment of this object is greater than that of the stack, then 367c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // increase the stack alignment to match. 368c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng MaxAlign = std::max(MaxAlign, Align); 369c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Adjust to alignment boundary 370c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng Offset = (Offset+Align-1)/Align*Align; 371c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 372c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng FFI->setObjectOffset(i, Offset); 373c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng Offset += FFI->getObjectSize(i); 374c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng } 375c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng } 376c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 37787f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // Make sure the special register scavenging spill slot is closest to the 37887f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // frame pointer if a frame pointer is required. 37987f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); 38087f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng if (RS && RegInfo->hasFP(Fn)) { 38187f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng int SFI = RS->getScavengingFrameIndex(); 38287f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng if (SFI >= 0) { 3835c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng // If stack grows down, we need to add size of the lowest 38487f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // address of the object. 38587f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng if (StackGrowsDown) 38687f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng Offset += FFI->getObjectSize(SFI); 38787f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 38887f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng unsigned Align = FFI->getObjectAlignment(SFI); 38987f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // Adjust to alignment boundary 39087f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng Offset = (Offset+Align-1)/Align*Align; 39187f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 39287f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng if (StackGrowsDown) { 39387f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng FFI->setObjectOffset(SFI, -Offset); // Set the computed offset 39487f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng } else { 39587f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng FFI->setObjectOffset(SFI, Offset); 39687f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng Offset += FFI->getObjectSize(SFI); 39787f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng } 39887f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng } 39987f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng } 40087f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 401c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng // Then assign frame offsets to stack objects that are not used to spill 402ad93d7fda53d92d07a3b3a2087e46de7cd695752Evan Cheng // callee saved registers. 40358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) { 404c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex) 405c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng continue; 40687f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng if (RS && (int)i == RS->getScavengingFrameIndex()) 40787f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng continue; 408c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng 409577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // If stack grows down, we need to add size of find the lowest 410577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner // address of the object. 411577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner if (StackGrowsDown) 412577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner Offset += FFI->getObjectSize(i); 41358b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 41458b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner unsigned Align = FFI->getObjectAlignment(i); 415ae232e7a1055033436370c0b3aecf054fa44d5e7Nate Begeman // If the alignment of this object is greater than that of the stack, then 416ae232e7a1055033436370c0b3aecf054fa44d5e7Nate Begeman // increase the stack alignment to match. 417ae232e7a1055033436370c0b3aecf054fa44d5e7Nate Begeman MaxAlign = std::max(MaxAlign, Align); 418ae232e7a1055033436370c0b3aecf054fa44d5e7Nate Begeman // Adjust to alignment boundary 419ae232e7a1055033436370c0b3aecf054fa44d5e7Nate Begeman Offset = (Offset+Align-1)/Align*Align; 420edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 421577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner if (StackGrowsDown) { 422577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner FFI->setObjectOffset(i, -Offset); // Set the computed offset 423577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner } else { 424edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman FFI->setObjectOffset(i, Offset); 425577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner Offset += FFI->getObjectSize(i); 426577aec14288b86ab1fb07e164375ebc7d3038cb7Chris Lattner } 42758b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner } 42858b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner 42987f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // Make sure the special register scavenging spill slot is closest to the 43087f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // stack pointer. 43187f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng if (RS) { 43287f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng int SFI = RS->getScavengingFrameIndex(); 43387f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng if (SFI >= 0) { 43487f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // If stack grows down, we need to add size of find the lowest 43587f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // address of the object. 43687f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng if (StackGrowsDown) 43787f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng Offset += FFI->getObjectSize(SFI); 43887f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 43987f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng unsigned Align = FFI->getObjectAlignment(SFI); 44087f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng // Adjust to alignment boundary 44187f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng Offset = (Offset+Align-1)/Align*Align; 44287f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 44387f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng if (StackGrowsDown) { 44487f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng FFI->setObjectOffset(SFI, -Offset); // Set the computed offset 44587f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng } else { 44687f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng FFI->setObjectOffset(SFI, Offset); 44787f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng Offset += FFI->getObjectSize(SFI); 44887f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng } 44987f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng } 45087f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng } 45187f8bf65dd869348dd4d2884a417e2e22ae4f981Evan Cheng 452367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng // Round up the size to a multiple of the alignment, but only if there are 453367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng // calls or alloca's in the function. This ensures that any calls to 454367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng // subroutines have their stack frames suitable aligned. 45502a20291410a6814c657b69901a57103d4861a07Evan Cheng if (!RegInfo->targetHandlesStackFrameRounding() && 45602a20291410a6814c657b69901a57103d4861a07Evan Cheng (FFI->hasCalls() || FFI->hasVarSizedObjects())) { 4575c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng // If we have reserved argument space for call sites in the function 4585c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng // immediately on entry to the current function, count it as part of the 4595c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng // overall stack size. 4605c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5Evan Cheng if (RegInfo->hasReservedCallFrame(Fn)) 461367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng Offset += FFI->getMaxCallFrameSize(); 462367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng 463367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng unsigned AlignMask = TFI.getStackAlignment() - 1; 464ea84c5ee952c62dd0c703c9852d7a60715e4a435Chris Lattner Offset = (Offset + AlignMask) & ~uint64_t(AlignMask); 465367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng } 466367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng 467367372a30c36776e31958f0dc38306f32b80aa7cEvan Cheng // Update frame info to pretend that this is part of the stack... 4687f7bbc2fdb833485ac3d865a405fd948e58e8ddbChris Lattner FFI->setStackSize(Offset+TFI.getOffsetOfLocalArea()); 469cbef8ba5f959b3c4f932005ceef5cf2e0d899f9bChris Lattner 470cbef8ba5f959b3c4f932005ceef5cf2e0d899f9bChris Lattner // Remember the required stack alignment in case targets need it to perform 471cbef8ba5f959b3c4f932005ceef5cf2e0d899f9bChris Lattner // dynamic stack alignment. 4724672f71ac4d056aa22d6b09838a3eb22a2e384e7Chris Lattner assert(FFI->getMaxAlignment() == MaxAlign && 4734672f71ac4d056aa22d6b09838a3eb22a2e384e7Chris Lattner "Stack alignment calculation broken!"); 4744ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner} 4754ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner 4764ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner 477c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng/// insertPrologEpilogCode - Scan the function for modified callee saved 478c2b4ec37dea2586765a04d74120e1b6197bbd804Evan Cheng/// registers, insert spill code for these callee saved registers, then add 4794ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner/// prolog and epilog code to the function. 4804ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner/// 4814ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattnervoid PEI::insertPrologEpilogCode(MachineFunction &Fn) { 4824ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner // Add prologue to the function... 4834ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner Fn.getTarget().getRegisterInfo()->emitPrologue(Fn); 4844ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner 4854ac7d7302b36a5d20f71b5c290c63a7f6c345289Chris Lattner // Add epilogue to restore the callee-save registers in each exiting block 4869bcdcd17c7219dbc68de2f11ca2de86471c8c390Chris Lattner const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); 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 489c0b9dc5be79f009d260edb5cd5e1d8346587aaa2Alkis Evlogimenos if (!I->empty() && TII.isReturn(I->back().getOpcode())) 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 // Remember how much SP has been adjustment to create the call frame. 5178e3347332120956538a6d882b02719e34b57f0cdEvan Cheng if (I->getOpcode() == FrameSetupOpcode || 5188e3347332120956538a6d882b02719e34b57f0cdEvan Cheng I->getOpcode() == FrameDestroyOpcode) { 5198e3347332120956538a6d882b02719e34b57f0cdEvan Cheng int Size = I->getOperand(0).getImmedValue(); 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; 5298e3347332120956538a6d882b02719e34b57f0cdEvan Cheng } else { 5308e3347332120956538a6d882b02719e34b57f0cdEvan Cheng I++; 5318e3347332120956538a6d882b02719e34b57f0cdEvan Cheng for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) 5328e3347332120956538a6d882b02719e34b57f0cdEvan Cheng if (MI->getOperand(i).isFrameIndex()) { 5338e3347332120956538a6d882b02719e34b57f0cdEvan Cheng // If this instruction has a FrameIndex operand, we need to use that 5348e3347332120956538a6d882b02719e34b57f0cdEvan Cheng // target machine register info object to eliminate it. 5358e3347332120956538a6d882b02719e34b57f0cdEvan Cheng MRI.eliminateFrameIndex(MI, SPAdj, RS); 5368e3347332120956538a6d882b02719e34b57f0cdEvan Cheng 5378e3347332120956538a6d882b02719e34b57f0cdEvan Cheng // Revisit the instruction in full. Some instructions (e.g. inline 5388e3347332120956538a6d882b02719e34b57f0cdEvan Cheng // asm instructions) can have multiple frame indices. 5398e3347332120956538a6d882b02719e34b57f0cdEvan Cheng --I; 5408e3347332120956538a6d882b02719e34b57f0cdEvan Cheng MI = 0; 5418e3347332120956538a6d882b02719e34b57f0cdEvan Cheng break; 5428e3347332120956538a6d882b02719e34b57f0cdEvan Cheng } 5438e3347332120956538a6d882b02719e34b57f0cdEvan Cheng } 54449dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng // Update register states. 5450ebe9c132c6b9c74b334f0c7503e702b499575d5Chris Lattner if (RS && MI) RS->forward(MI); 54649dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng } 5478e3347332120956538a6d882b02719e34b57f0cdEvan Cheng assert(SPAdj == 0 && "Unbalanced call frame setup / destroy pairs?"); 54849dd06461a7e027a6c938f0570297d46f2f34218Evan Cheng } 54958b3328ac709a5706a8bfa522012ed90f1b4d4bdChris Lattner} 550