//
//===----------------------------------------------------------------------===//
-#include "llvm/Pass.h"
-#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/FunctionFrameInfo.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/MRegisterInfo.h"
-#include "llvm/Target/MachineFrameInfo.h"
-#include "llvm/Target/MachineInstrInfo.h"
+#include "llvm/Target/TargetFrameInfo.h"
+#include "llvm/Target/TargetInstrInfo.h"
namespace {
- struct PEI : public FunctionPass {
- bool runOnFunction(Function &Fn) {
- return runOnMachineFunction(MachineFunction::get(&Fn));
+ struct PEI : public MachineFunctionPass {
+ const char *getPassName() const {
+ return "Prolog/Epilog Insertion & Frame Finalization";
}
/// runOnMachineFunction - Insert prolog/epilog code and replace abstract
// Calculate actual frame offsets for all of the abstract stack objects...
calculateFrameObjectOffsets(Fn);
+ // Add prolog and epilog code to the function.
+ insertPrologEpilogCode(Fn);
+
// Replace all MO_FrameIndex operands with physical register references
// and actual offsets.
//
replaceFrameIndices(Fn);
-
- // Add prolog and epilog code to the function.
- insertPrologEpilogCode(Fn);
return true;
}
MachineOperand &MO = (*I)->getOperand(i);
assert(!MO.isVirtualRegister() &&
"Register allocation must be performed!");
- if (MO.isPhysicalRegister() && MO.opIsDef())
+ if (MO.isPhysicalRegister() &&
+ (MO.opIsDefOnly() || MO.opIsDefAndUse()))
ModifiedRegs[MO.getReg()] = true; // Register is modified
}
++I;
}
- FunctionFrameInfo *FFI = Fn.getFrameInfo();
+ MachineFrameInfo *FFI = Fn.getFrameInfo();
FFI->setHasCalls(HasCalls);
FFI->setMaxCallFrameSize(MaxCallFrameSize);
// stack slots for them.
std::vector<int> StackSlots;
for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) {
- const TargetRegisterClass *RC = RegInfo->getRegClass(RegsToSave[i]);
- int FrameIdx = FFI->CreateStackObject(RC->getSize(), RC->getAlignment());
+ int FrameIdx = FFI->CreateStackObject(RegInfo->getRegClass(RegsToSave[i]));
StackSlots.push_back(FrameIdx);
}
}
// Add code to restore the callee-save registers in each exiting block.
- const MachineInstrInfo &MII = Fn.getTarget().getInstrInfo();
+ const TargetInstrInfo &TII = Fn.getTarget().getInstrInfo();
for (MachineFunction::iterator FI = Fn.begin(), E = Fn.end(); FI != E; ++FI) {
// If last instruction is a return instruction, add an epilogue
- if (MII.isReturn(FI->back()->getOpcode())) {
+ if (!FI->empty() && TII.isReturn(FI->back()->getOpcode())) {
MBB = FI; I = MBB->end()-1;
for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) {
assert(StackGrowsDown && "Only tested on stack down growing targets!");
// Loop over all of the stack objects, assigning sequential addresses...
- FunctionFrameInfo *FFI = Fn.getFrameInfo();
+ MachineFrameInfo *FFI = Fn.getFrameInfo();
+
+ unsigned StackAlignment = TFI.getStackAlignment();
// Start at the beginning of the local area...
- int Offset = -TFI.getOffsetOfLocalArea();
+ int Offset = TFI.getOffsetOfLocalArea();
for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) {
Offset += FFI->getObjectSize(i); // Allocate Size bytes...
unsigned Align = FFI->getObjectAlignment(i);
+ assert(Align <= StackAlignment && "Cannot align stack object to higher "
+ "alignment boundary than the stack itself!");
Offset = (Offset+Align-1)/Align*Align; // Adjust to Alignment boundary...
FFI->setObjectOffset(i, -Offset); // Set the computed offset
}
// Align the final stack pointer offset...
- unsigned StackAlign = TFI.getStackAlignment();
- Offset = (Offset+StackAlign-1)/StackAlign*StackAlign;
+ Offset = (Offset+StackAlignment-1)/StackAlignment*StackAlignment;
// Set the final value of the stack pointer...
- FFI->setStackSize(Offset);
+ FFI->setStackSize(Offset-TFI.getOffsetOfLocalArea());
+}
+
+
+/// insertPrologEpilogCode - Scan the function for modified caller saved
+/// registers, insert spill code for these caller saved registers, then add
+/// prolog and epilog code to the function.
+///
+void PEI::insertPrologEpilogCode(MachineFunction &Fn) {
+ // Add prologue to the function...
+ Fn.getTarget().getRegisterInfo()->emitPrologue(Fn);
+
+ // Add epilogue to restore the callee-save registers in each exiting block
+ const TargetInstrInfo &TII = Fn.getTarget().getInstrInfo();
+ for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) {
+ // If last instruction is a return instruction, add an epilogue
+ if (!I->empty() && TII.isReturn(I->back()->getOpcode()))
+ Fn.getTarget().getRegisterInfo()->emitEpilogue(Fn, *I);
+ }
}
break;
}
}
-
-
-/// insertPrologEpilogCode - Scan the function for modified caller saved
-/// registers, insert spill code for these caller saved registers, then add
-/// prolog and epilog code to the function.
-///
-void PEI::insertPrologEpilogCode(MachineFunction &Fn) {
- // Add prologue to the function...
- Fn.getTarget().getRegisterInfo()->emitPrologue(Fn);
-
- // Add epilogue to restore the callee-save registers in each exiting block
- const MachineInstrInfo &MII = Fn.getTarget().getInstrInfo();
- for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) {
- // If last instruction is a return instruction, add an epilogue
- if (MII.isReturn(I->back()->getOpcode()))
- Fn.getTarget().getRegisterInfo()->emitEpilogue(Fn, *I);
- }
-}