PrologEpilogInserter.cpp revision 49d780670d07fa86f61ab1cb006dcd9689983978
17be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org//===-- PrologEpilogInserter.cpp - Insert Prolog/Epilog code in function --===// 243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The LLVM Compiler Infrastructure 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// This file is distributed under the University of Illinois Open Source 643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// License. See LICENSE.TXT for details. 743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//===----------------------------------------------------------------------===// 943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// This pass is responsible for finalizing the functions frame layout, saving 1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// callee saved registers, and for emitting prolog & epilog code for the 1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// function. 1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// This pass must be run after register allocation. After this pass is 1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// executed, it is illegal to construct MO_FrameIndex operands. 1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// This pass provides an optional shrink wrapping variant of prolog/epilog 1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// insertion, enabled via --shrink-wrap. See ShrinkWrapping.cpp. 1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//===----------------------------------------------------------------------===// 2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "PrologEpilogInserter.h" 2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "llvm/CodeGen/MachineDominators.h" 2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "llvm/CodeGen/MachineLoopInfo.h" 2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "llvm/CodeGen/MachineInstr.h" 2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "llvm/CodeGen/MachineFrameInfo.h" 2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "llvm/CodeGen/MachineModuleInfo.h" 2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "llvm/CodeGen/MachineRegisterInfo.h" 292efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org#include "llvm/CodeGen/RegisterScavenging.h" 3043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "llvm/Target/TargetMachine.h" 3141044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org#include "llvm/Target/TargetRegisterInfo.h" 3241044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org#include "llvm/Target/TargetFrameInfo.h" 3341044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org#include "llvm/Target/TargetInstrInfo.h" 3443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "llvm/Support/Compiler.h" 3532280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org#include "llvm/ADT/STLExtras.h" 3632280cf2786219b2d9a668f7f00778fb59ac40b3mstarzinger@chromium.org#include <climits> 3743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenusing namespace llvm; 3943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenchar PEI::ID = 0; 4143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 42212ac23f8231d169b4aa6737d762099993020826kasper.lundstatic RegisterPass<PEI> 4304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.orgX("prologepilog", "Prologue/Epilogue Insertion"); 4404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org 453d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org/// createPrologEpilogCodeInserter - This function returns a pass that inserts 463d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org/// prolog and epilog code, and eliminates abstract frame references. 4704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org/// 4804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.orgFunctionPass *llvm::createPrologEpilogCodeInserter() { return new PEI(); } 492c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org 5043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/// runOnMachineFunction - Insert prolog/epilog code and replace abstract 5143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/// frame indexes with appropriate references. 5243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/// 5343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool PEI::runOnMachineFunction(MachineFunction &Fn) { 5443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo(); 5541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org RS = TRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : NULL; 5641044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org 5743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get MachineModuleInfo so that we can track the construction of the 5841044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org // frame. 5941044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org if (MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>()) 6041044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org Fn.getFrameInfo()->setMachineModuleInfo(MMI); 6141044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org 6241044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org // Calculate the MaxCallFrameSize and HasCalls variables for the function's 6341044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org // frame information. Also eliminates call frame pseudo instructions. 6441044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org calculateCallsInformation(Fn); 6541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org 66eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Allow the target machine to make some adjustments to the function 6743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // e.g. UsedPhysRegs before calculateCalleeSavedRegisters. 683291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org TRI->processFunctionBeforeCalleeSavedScan(Fn, RS); 693291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 70662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org // Scan the function for modified callee saved registers and insert spill code 71662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org // for any callee saved registers that are modified. 72639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org calculateCalleeSavedRegisters(Fn); 733291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org 7441044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org // Determine placement of CSR spill/restore code: 7541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org // - with shrink wrapping, place spills and restores to tightly 7641044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org // enclose regions in the Machine CFG of the function where 7741044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org // they are used. Without shrink wrapping 7841044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org // - default (no shrink wrapping), place all spills in the 7941044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org // entry block, all restores in return blocks. 8041044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org placeCSRSpillsAndRestores(Fn); 8143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 82ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // Add the code to save and restore the callee saved registers 83ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org insertCSRSpillsAndRestores(Fn); 84ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 85ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // Allow the target machine to make final modifications to the function 86ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // before the frame layout is finalized. 87ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org TRI->processFunctionBeforeFrameFinalized(Fn); 88ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 89ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // Calculate actual frame offsets for all abstract stack objects... 908496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org calculateFrameObjectOffsets(Fn); 918496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org 928496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org // Add prolog and epilog code to the function. This function is required 938496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org // to align the stack frame as necessary for any stack variables or 94c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org // called functions. Because of this, calculateCalleeSavedRegisters 95c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org // must be called before this function in order to set the HasCalls 96c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org // and MaxCallFrameSize variables. 9741044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org insertPrologEpilogCode(Fn); 98b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org 99b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org // Replace all MO_FrameIndex operands with physical register references 100b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org // and actual offsets. 101b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org // 10243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen replaceFrameIndices(Fn); 10343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1048496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org delete RS; 10543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen clearAllSets(); 10643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return true; 10743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 108f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 1096141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org#if 0 1102abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.orgvoid PEI::getAnalysisUsage(AnalysisUsage &AU) const { 1116141cbe3fd2be496590a3d5fe89b263c87eee58aager@chromium.org AU.setPreservesCFG(); 112b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org if (ShrinkWrapping || ShrinkWrapFunc != "") { 113fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org AU.addRequired<MachineLoopInfo>(); 114fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org AU.addRequired<MachineDominatorTree>(); 115fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org } 116ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org AU.addPreserved<MachineLoopInfo>(); 1172abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org AU.addPreserved<MachineDominatorTree>(); 1182abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org MachineFunctionPass::getAnalysisUsage(AU); 1192abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org} 120f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org#endif 1212abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org 1222abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org/// calculateCallsInformation - Calculate the MaxCallFrameSize and HasCalls 1232abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org/// variables for the function's frame information and eliminate call frame 1242abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org/// pseudo instructions. 1252abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.orgvoid PEI::calculateCallsInformation(MachineFunction &Fn) { 126f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); 1271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 128b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org unsigned MaxCallFrameSize = 0; 129b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org bool HasCalls = false; 1300c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 13143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get the function call frame set-up and tear-down instruction opcode 132dff694e8cc18aa9640e92962de2699b9d07a7690vegorov@chromium.org int FrameSetupOpcode = RegInfo->getCallFrameSetupOpcode(); 133dff694e8cc18aa9640e92962de2699b9d07a7690vegorov@chromium.org int FrameDestroyOpcode = RegInfo->getCallFrameDestroyOpcode(); 13434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 13534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // Early exit for targets which have no call frame setup/destroy pseudo 1364980dff4208f9b77bc5320af43d7cc4b2a3d9688ricow@chromium.org // instructions. 13734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (FrameSetupOpcode == -1 && FrameDestroyOpcode == -1) 13834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org return; 13934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 14034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org std::vector<MachineBasicBlock::iterator> FrameSDOps; 14134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) 14234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) 14334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (I->getOpcode() == FrameSetupOpcode || 14434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org I->getOpcode() == FrameDestroyOpcode) { 145dff694e8cc18aa9640e92962de2699b9d07a7690vegorov@chromium.org assert(I->getNumOperands() >= 1 && "Call Frame Setup/Destroy Pseudo" 146bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org " instructions should have a single immediate argument!"); 147bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org unsigned Size = I->getOperand(0).getImm(); 148bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org if (Size > MaxCallFrameSize) MaxCallFrameSize = Size; 149bbbda924f939464825b508976aabe7ed128605cbmachenbach@chromium.org HasCalls = true; 150394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com FrameSDOps.push_back(I); 151394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 152394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 153394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com MachineFrameInfo *FFI = Fn.getFrameInfo(); 154394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com FFI->setHasCalls(HasCalls); 15541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org FFI->setMaxCallFrameSize(MaxCallFrameSize); 15641044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org 157486075aa3f2e6d0031ff182961b9eab00e1081d8jkummerow@chromium.org for (std::vector<MachineBasicBlock::iterator>::iterator 15865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org i = FrameSDOps.begin(), e = FrameSDOps.end(); i != e; ++i) { 159e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org MachineBasicBlock::iterator I = *i; 16069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 161b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org // If call frames are not being included as part of the stack frame, and 162b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org // there is no dynamic allocation (therefore referencing frame slots off 163b95b98b0c30bcd40b657aa45f6cd75a46a4772adfschneider@chromium.org // sp), leave the pseudo ops alone. We'll eliminate them later. 164d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org if (RegInfo->hasReservedCallFrame(Fn) || RegInfo->hasFP(Fn)) 1657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org RegInfo->eliminateCallFramePseudoInstr(Fn, *I->getParent(), I); 166d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org } 16743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 1680cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 1696a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org 1706a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org/// calculateCalleeSavedRegisters - Scan the function for modified callee saved 171a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org/// registers. 1720cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.orgvoid PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) { 173034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); 174fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org const TargetFrameInfo *TFI = Fn.getTarget().getFrameInfo(); 1750cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org MachineFrameInfo *FFI = Fn.getFrameInfo(); 1760cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 1770cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org // Get the callee saved register list... 1780cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org const unsigned *CSRegs = RegInfo->getCalleeSavedRegs(&Fn); 179690083842e7c67a362017dae50909d4bb0b2a9c2mstarzinger@chromium.org 180690083842e7c67a362017dae50909d4bb0b2a9c2mstarzinger@chromium.org // These are used to keep track the callee-save area. Initialize them. 181690083842e7c67a362017dae50909d4bb0b2a9c2mstarzinger@chromium.org MinCSFrameIndex = INT_MAX; 182690083842e7c67a362017dae50909d4bb0b2a9c2mstarzinger@chromium.org MaxCSFrameIndex = 0; 183690083842e7c67a362017dae50909d4bb0b2a9c2mstarzinger@chromium.org 18441044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org // Early exit for targets which have no callee saved registers. 18541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org if (CSRegs == 0 || CSRegs[0] == 0) 18643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return; 1877be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 1887be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org // Figure out which *callee saved* registers are modified by the current 189bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // function, thus needing to be saved and restored in the prolog/epilog. 1907be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org const TargetRegisterClass * const *CSRegClasses = 1917be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org RegInfo->getCalleeSavedRegClasses(&Fn); 1927be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 1937be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org std::vector<CalleeSavedInfo> CSI; 1947be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org for (unsigned i = 0; CSRegs[i]; ++i) { 1955d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org unsigned Reg = CSRegs[i]; 1965d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org if (Fn.getRegInfo().isPhysRegUsed(Reg)) { 1975f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // If the reg is modified, save it! 1985f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org CSI.push_back(CalleeSavedInfo(Reg, CSRegClasses[i])); 1995d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org } else { 2002abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg); 2012abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org *AliasSet; ++AliasSet) { // Check alias registers too. 2024efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org if (Fn.getRegInfo().isPhysRegUsed(*AliasSet)) { 2034efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org CSI.push_back(CalleeSavedInfo(Reg, CSRegClasses[i])); 2044efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org break; 2054efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org } 2064efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org } 2074efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org } 2084efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org } 2094efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 2104efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org if (CSI.empty()) 2114efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org return; // Early exit if no callee saved registers are modified! 2124efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 2134efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org unsigned NumFixedSpillSlots; 2144efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org const std::pair<unsigned,int> *FixedSpillSlots = 2154efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org TFI->getCalleeSavedSpillSlots(NumFixedSpillSlots); 2164efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 2174efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org // Now that we know which registers need to be saved and restored, allocate 2184efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org // stack slots for them. 2194efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org for (std::vector<CalleeSavedInfo>::iterator 2204efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org I = CSI.begin(), E = CSI.end(); I != E; ++I) { 2214efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org unsigned Reg = I->getReg(); 2224efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org const TargetRegisterClass *RC = I->getRegClass(); 2234efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 2244efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org int FrameIdx; 2254efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org if (RegInfo->hasReservedSpillSlot(Fn, Reg, FrameIdx)) { 2264efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org I->setFrameIdx(FrameIdx); 2274efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org continue; 2284efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org } 2294efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org 2304efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org // Check to see if this physreg must be spilled to a particular stack slot 2314efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org // on this target. 2322abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org const std::pair<unsigned,int> *FixedSlot = FixedSpillSlots; 2339d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com while (FixedSlot != FixedSpillSlots+NumFixedSpillSlots && 234efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org FixedSlot->first != Reg) 235bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org ++FixedSlot; 236bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 2377be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org if (FixedSlot == FixedSpillSlots + NumFixedSpillSlots) { 2387be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org // Nope, just spill it anywhere convenient. 239bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org unsigned Align = RC->getAlignment(); 240bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org unsigned StackAlign = TFI->getStackAlignment(); 241bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 24230ce411529579186181838984710b0b0980857aaricow@chromium.org // We may not be able to satisfy the desired alignment specification of 243ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // the TargetRegisterClass if the stack alignment is smaller. Use the 244ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // min. 245ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com Align = std::min(Align, StackAlign); 246ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com FrameIdx = FFI->CreateStackObject(RC->getSize(), Align); 247ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com if ((unsigned)FrameIdx < MinCSFrameIndex) MinCSFrameIndex = FrameIdx; 248ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com if ((unsigned)FrameIdx > MaxCSFrameIndex) MaxCSFrameIndex = FrameIdx; 249ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com } else { 250ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // Spill it to the stack where we must. 251ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com FrameIdx = FFI->CreateFixedObject(RC->getSize(), FixedSlot->second); 2521805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org } 25330ce411529579186181838984710b0b0980857aaricow@chromium.org 25430ce411529579186181838984710b0b0980857aaricow@chromium.org I->setFrameIdx(FrameIdx); 25530ce411529579186181838984710b0b0980857aaricow@chromium.org } 25630ce411529579186181838984710b0b0980857aaricow@chromium.org 25730ce411529579186181838984710b0b0980857aaricow@chromium.org FFI->setCalleeSavedInfo(CSI); 25830ce411529579186181838984710b0b0980857aaricow@chromium.org} 25930ce411529579186181838984710b0b0980857aaricow@chromium.org 26030ce411529579186181838984710b0b0980857aaricow@chromium.org/// insertCSRSpillsAndRestores - Insert spill and restore code for 2611805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org/// callee saved registers used in the function, handling shrink wrapping. 2621805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org/// 2631805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgvoid PEI::insertCSRSpillsAndRestores(MachineFunction &Fn) { 2641805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // Get callee saved register information. 2651805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org MachineFrameInfo *FFI = Fn.getFrameInfo(); 2661805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org const std::vector<CalleeSavedInfo> &CSI = FFI->getCalleeSavedInfo(); 2671805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 2681805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // Early exit if no callee saved registers are modified! 2691805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org if (CSI.empty()) 2701805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org return; 2711805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 2721805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); 2731805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org MachineBasicBlock::iterator I; 2741805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 275034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org if (! ShrinkWrapThisFunction) { 276034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org // Spill using target interface. 277034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org I = EntryBlock->begin(); 278034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org if (!TII.spillCalleeSavedRegisters(*EntryBlock, I, CSI)) { 279034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 280034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org // Add the callee-saved register as live-in. 2814ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org // It's killed at the spill. 2824ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org EntryBlock->addLiveIn(CSI[i].getReg()); 2834ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org 2844ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org // Insert the spill to the stack frame. 2854ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org TII.storeRegToStackSlot(*EntryBlock, I, CSI[i].getReg(), true, 286 CSI[i].getFrameIdx(), CSI[i].getRegClass()); 287 } 288 } 289 290 // Restore using target interface. 291 for (unsigned ri = 0, re = ReturnBlocks.size(); ri != re; ++ri) { 292 MachineBasicBlock* MBB = ReturnBlocks[ri]; 293 I = MBB->end(); --I; 294 295 // Skip over all terminator instructions, which are part of the return 296 // sequence. 297 MachineBasicBlock::iterator I2 = I; 298 while (I2 != MBB->begin() && (--I2)->getDesc().isTerminator()) 299 I = I2; 300 301 bool AtStart = I == MBB->begin(); 302 MachineBasicBlock::iterator BeforeI = I; 303 if (!AtStart) 304 --BeforeI; 305 306 // Restore all registers immediately before the return and any 307 // terminators that preceed it. 308 if (!TII.restoreCalleeSavedRegisters(*MBB, I, CSI)) { 309 for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 310 TII.loadRegFromStackSlot(*MBB, I, CSI[i].getReg(), 311 CSI[i].getFrameIdx(), 312 CSI[i].getRegClass()); 313 assert(I != MBB->begin() && 314 "loadRegFromStackSlot didn't insert any code!"); 315 // Insert in reverse order. loadRegFromStackSlot can insert 316 // multiple instructions. 317 if (AtStart) 318 I = MBB->begin(); 319 else { 320 I = BeforeI; 321 ++I; 322 } 323 } 324 } 325 } 326 return; 327 } 328 329 // Insert spills. 330 std::vector<CalleeSavedInfo> blockCSI; 331 for (CSRegBlockMap::iterator BI = CSRSave.begin(), 332 BE = CSRSave.end(); BI != BE; ++BI) { 333 MachineBasicBlock* MBB = BI->first; 334 CSRegSet save = BI->second; 335 336 if (save.empty()) 337 continue; 338 339 blockCSI.clear(); 340 for (CSRegSet::iterator RI = save.begin(), 341 RE = save.end(); RI != RE; ++RI) { 342 blockCSI.push_back(CSI[*RI]); 343 } 344 assert(blockCSI.size() > 0 && 345 "Could not collect callee saved register info"); 346 347 I = MBB->begin(); 348 349 // When shrink wrapping, use stack slot stores/loads. 350 for (unsigned i = 0, e = blockCSI.size(); i != e; ++i) { 351 // Add the callee-saved register as live-in. 352 // It's killed at the spill. 353 MBB->addLiveIn(blockCSI[i].getReg()); 354 355 // Insert the spill to the stack frame. 356 TII.storeRegToStackSlot(*MBB, I, blockCSI[i].getReg(), 357 true, 358 blockCSI[i].getFrameIdx(), 359 blockCSI[i].getRegClass()); 360 } 361 } 362 363 for (CSRegBlockMap::iterator BI = CSRRestore.begin(), 364 BE = CSRRestore.end(); BI != BE; ++BI) { 365 MachineBasicBlock* MBB = BI->first; 366 CSRegSet restore = BI->second; 367 368 if (restore.empty()) 369 continue; 370 371 blockCSI.clear(); 372 for (CSRegSet::iterator RI = restore.begin(), 373 RE = restore.end(); RI != RE; ++RI) { 374 blockCSI.push_back(CSI[*RI]); 375 } 376 assert(blockCSI.size() > 0 && 377 "Could not find callee saved register info"); 378 379 // If MBB is empty and needs restores, insert at the _beginning_. 380 if (MBB->empty()) { 381 I = MBB->begin(); 382 } else { 383 I = MBB->end(); 384 --I; 385 386 // Skip over all terminator instructions, which are part of the 387 // return sequence. 388 if (! I->getDesc().isTerminator()) { 389 ++I; 390 } else { 391 MachineBasicBlock::iterator I2 = I; 392 while (I2 != MBB->begin() && (--I2)->getDesc().isTerminator()) 393 I = I2; 394 } 395 } 396 397 bool AtStart = I == MBB->begin(); 398 MachineBasicBlock::iterator BeforeI = I; 399 if (!AtStart) 400 --BeforeI; 401 402 // Restore all registers immediately before the return and any 403 // terminators that preceed it. 404 for (unsigned i = 0, e = blockCSI.size(); i != e; ++i) { 405 TII.loadRegFromStackSlot(*MBB, I, blockCSI[i].getReg(), 406 blockCSI[i].getFrameIdx(), 407 blockCSI[i].getRegClass()); 408 assert(I != MBB->begin() && 409 "loadRegFromStackSlot didn't insert any code!"); 410 // Insert in reverse order. loadRegFromStackSlot can insert 411 // multiple instructions. 412 if (AtStart) 413 I = MBB->begin(); 414 else { 415 I = BeforeI; 416 ++I; 417 } 418 } 419 } 420} 421 422/// AdjustStackOffset - Helper function used to adjust the stack frame offset. 423static inline void 424AdjustStackOffset(MachineFrameInfo *FFI, int FrameIdx, 425 bool StackGrowsDown, int64_t &Offset, 426 unsigned &MaxAlign) { 427 // If stack grows down, we need to add size of find the lowest address of the 428 // object. 429 if (StackGrowsDown) 430 Offset += FFI->getObjectSize(FrameIdx); 431 432 unsigned Align = FFI->getObjectAlignment(FrameIdx); 433 434 // If the alignment of this object is greater than that of the stack, then 435 // increase the stack alignment to match. 436 MaxAlign = std::max(MaxAlign, Align); 437 438 // Adjust to alignment boundary. 439 Offset = (Offset + Align - 1) / Align * Align; 440 441 if (StackGrowsDown) { 442 FFI->setObjectOffset(FrameIdx, -Offset); // Set the computed offset 443 } else { 444 FFI->setObjectOffset(FrameIdx, Offset); 445 Offset += FFI->getObjectSize(FrameIdx); 446 } 447} 448 449/// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the 450/// abstract stack objects. 451/// 452void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { 453 const TargetFrameInfo &TFI = *Fn.getTarget().getFrameInfo(); 454 455 bool StackGrowsDown = 456 TFI.getStackGrowthDirection() == TargetFrameInfo::StackGrowsDown; 457 458 // Loop over all of the stack objects, assigning sequential addresses... 459 MachineFrameInfo *FFI = Fn.getFrameInfo(); 460 461 unsigned MaxAlign = FFI->getMaxAlignment(); 462 463 // Start at the beginning of the local area. 464 // The Offset is the distance from the stack top in the direction 465 // of stack growth -- so it's always nonnegative. 466 int64_t Offset = TFI.getOffsetOfLocalArea(); 467 if (StackGrowsDown) 468 Offset = -Offset; 469 assert(Offset >= 0 470 && "Local area offset should be in direction of stack growth"); 471 472 // If there are fixed sized objects that are preallocated in the local area, 473 // non-fixed objects can't be allocated right at the start of local area. 474 // We currently don't support filling in holes in between fixed sized 475 // objects, so we adjust 'Offset' to point to the end of last fixed sized 476 // preallocated object. 477 for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) { 478 int64_t FixedOff; 479 if (StackGrowsDown) { 480 // The maximum distance from the stack pointer is at lower address of 481 // the object -- which is given by offset. For down growing stack 482 // the offset is negative, so we negate the offset to get the distance. 483 FixedOff = -FFI->getObjectOffset(i); 484 } else { 485 // The maximum distance from the start pointer is at the upper 486 // address of the object. 487 FixedOff = FFI->getObjectOffset(i) + FFI->getObjectSize(i); 488 } 489 if (FixedOff > Offset) Offset = FixedOff; 490 } 491 492 // First assign frame offsets to stack objects that are used to spill 493 // callee saved registers. 494 if (StackGrowsDown) { 495 for (unsigned i = MinCSFrameIndex; i <= MaxCSFrameIndex; ++i) { 496 // If stack grows down, we need to add size of find the lowest 497 // address of the object. 498 Offset += FFI->getObjectSize(i); 499 500 unsigned Align = FFI->getObjectAlignment(i); 501 // If the alignment of this object is greater than that of the stack, 502 // then increase the stack alignment to match. 503 MaxAlign = std::max(MaxAlign, Align); 504 // Adjust to alignment boundary 505 Offset = (Offset+Align-1)/Align*Align; 506 507 FFI->setObjectOffset(i, -Offset); // Set the computed offset 508 } 509 } else { 510 int MaxCSFI = MaxCSFrameIndex, MinCSFI = MinCSFrameIndex; 511 for (int i = MaxCSFI; i >= MinCSFI ; --i) { 512 unsigned Align = FFI->getObjectAlignment(i); 513 // If the alignment of this object is greater than that of the stack, 514 // then increase the stack alignment to match. 515 MaxAlign = std::max(MaxAlign, Align); 516 // Adjust to alignment boundary 517 Offset = (Offset+Align-1)/Align*Align; 518 519 FFI->setObjectOffset(i, Offset); 520 Offset += FFI->getObjectSize(i); 521 } 522 } 523 524 // Make sure the special register scavenging spill slot is closest to the 525 // frame pointer if a frame pointer is required. 526 const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); 527 if (RS && RegInfo->hasFP(Fn)) { 528 int SFI = RS->getScavengingFrameIndex(); 529 if (SFI >= 0) 530 AdjustStackOffset(FFI, SFI, StackGrowsDown, Offset, MaxAlign); 531 } 532 533 // Make sure that the stack protector comes before the local variables on the 534 // stack. 535 if (FFI->getStackProtectorIndex() >= 0) 536 AdjustStackOffset(FFI, FFI->getStackProtectorIndex(), StackGrowsDown, 537 Offset, MaxAlign); 538 539 // Then assign frame offsets to stack objects that are not used to spill 540 // callee saved registers. 541 for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) { 542 if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex) 543 continue; 544 if (RS && (int)i == RS->getScavengingFrameIndex()) 545 continue; 546 if (FFI->isDeadObjectIndex(i)) 547 continue; 548 if (FFI->getStackProtectorIndex() == (int)i) 549 continue; 550 551 AdjustStackOffset(FFI, i, StackGrowsDown, Offset, MaxAlign); 552 } 553 554 // Make sure the special register scavenging spill slot is closest to the 555 // stack pointer. 556 if (RS && !RegInfo->hasFP(Fn)) { 557 int SFI = RS->getScavengingFrameIndex(); 558 if (SFI >= 0) 559 AdjustStackOffset(FFI, SFI, StackGrowsDown, Offset, MaxAlign); 560 } 561 562 // Round up the size to a multiple of the alignment, but only if there are 563 // calls or alloca's in the function. This ensures that any calls to 564 // subroutines have their stack frames suitable aligned. 565 // Also do this if we need runtime alignment of the stack. In this case 566 // offsets will be relative to SP not FP; round up the stack size so this 567 // works. 568 if (!RegInfo->targetHandlesStackFrameRounding() && 569 (FFI->hasCalls() || FFI->hasVarSizedObjects() || 570 (RegInfo->needsStackRealignment(Fn) && 571 FFI->getObjectIndexEnd() != 0))) { 572 // If we have reserved argument space for call sites in the function 573 // immediately on entry to the current function, count it as part of the 574 // overall stack size. 575 if (RegInfo->hasReservedCallFrame(Fn)) 576 Offset += FFI->getMaxCallFrameSize(); 577 578 unsigned AlignMask = std::max(TFI.getStackAlignment(),MaxAlign) - 1; 579 Offset = (Offset + AlignMask) & ~uint64_t(AlignMask); 580 } 581 582 // Update frame info to pretend that this is part of the stack... 583 FFI->setStackSize(Offset+TFI.getOffsetOfLocalArea()); 584 585 // Remember the required stack alignment in case targets need it to perform 586 // dynamic stack alignment. 587 FFI->setMaxAlignment(MaxAlign); 588} 589 590 591/// insertPrologEpilogCode - Scan the function for modified callee saved 592/// registers, insert spill code for these callee saved registers, then add 593/// prolog and epilog code to the function. 594/// 595void PEI::insertPrologEpilogCode(MachineFunction &Fn) { 596 const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo(); 597 598 // Add prologue to the function... 599 TRI->emitPrologue(Fn); 600 601 // Add epilogue to restore the callee-save registers in each exiting block 602 for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) { 603 // If last instruction is a return instruction, add an epilogue 604 if (!I->empty() && I->back().getDesc().isReturn()) 605 TRI->emitEpilogue(Fn, *I); 606 } 607} 608 609 610/// replaceFrameIndices - Replace all MO_FrameIndex operands with physical 611/// register references and actual offsets. 612/// 613void PEI::replaceFrameIndices(MachineFunction &Fn) { 614 if (!Fn.getFrameInfo()->hasStackObjects()) return; // Nothing to do? 615 616 const TargetMachine &TM = Fn.getTarget(); 617 assert(TM.getRegisterInfo() && "TM::getRegisterInfo() must be implemented!"); 618 const TargetRegisterInfo &TRI = *TM.getRegisterInfo(); 619 const TargetFrameInfo *TFI = TM.getFrameInfo(); 620 bool StackGrowsDown = 621 TFI->getStackGrowthDirection() == TargetFrameInfo::StackGrowsDown; 622 int FrameSetupOpcode = TRI.getCallFrameSetupOpcode(); 623 int FrameDestroyOpcode = TRI.getCallFrameDestroyOpcode(); 624 625 for (MachineFunction::iterator BB = Fn.begin(), 626 E = Fn.end(); BB != E; ++BB) { 627 int SPAdj = 0; // SP offset due to call frame setup / destroy. 628 if (RS) RS->enterBasicBlock(BB); 629 630 for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) { 631 if (I->getOpcode() == TargetInstrInfo::DECLARE) { 632 // Ignore it. 633 ++I; 634 continue; 635 } 636 637 if (I->getOpcode() == FrameSetupOpcode || 638 I->getOpcode() == FrameDestroyOpcode) { 639 // Remember how much SP has been adjusted to create the call 640 // frame. 641 int Size = I->getOperand(0).getImm(); 642 643 if ((!StackGrowsDown && I->getOpcode() == FrameSetupOpcode) || 644 (StackGrowsDown && I->getOpcode() == FrameDestroyOpcode)) 645 Size = -Size; 646 647 SPAdj += Size; 648 649 MachineBasicBlock::iterator PrevI = BB->end(); 650 if (I != BB->begin()) PrevI = prior(I); 651 TRI.eliminateCallFramePseudoInstr(Fn, *BB, I); 652 653 // Visit the instructions created by eliminateCallFramePseudoInstr(). 654 if (PrevI == BB->end()) 655 I = BB->begin(); // The replaced instr was the first in the block. 656 else 657 I = next(PrevI); 658 continue; 659 } 660 661 MachineInstr *MI = I; 662 bool DoIncr = true; 663 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) 664 if (MI->getOperand(i).isFI()) { 665 // Some instructions (e.g. inline asm instructions) can have 666 // multiple frame indices and/or cause eliminateFrameIndex 667 // to insert more than one instruction. We need the register 668 // scavenger to go through all of these instructions so that 669 // it can update its register information. We keep the 670 // iterator at the point before insertion so that we can 671 // revisit them in full. 672 bool AtBeginning = (I == BB->begin()); 673 if (!AtBeginning) --I; 674 675 // If this instruction has a FrameIndex operand, we need to 676 // use that target machine register info object to eliminate 677 // it. 678 679 TRI.eliminateFrameIndex(MI, SPAdj, RS); 680 681 // Reset the iterator if we were at the beginning of the BB. 682 if (AtBeginning) { 683 I = BB->begin(); 684 DoIncr = false; 685 } 686 687 MI = 0; 688 break; 689 } 690 691 if (DoIncr && I != BB->end()) ++I; 692 693 // Update register states. 694 if (RS && MI) RS->forward(MI); 695 } 696 697 assert(SPAdj == 0 && "Unbalanced call frame setup / destroy pairs?"); 698 } 699} 700 701