2016-03-28 15:09:54 +02:00
|
|
|
//===-- LanaiFrameLowering.cpp - Lanai Frame Information ------------------===//
|
|
|
|
//
|
2019-01-19 09:50:56 +01:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2016-03-28 15:09:54 +02:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file contains the Lanai implementation of TargetFrameLowering class.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "LanaiFrameLowering.h"
|
|
|
|
|
2019-06-03 19:02:15 +02:00
|
|
|
#include "LanaiAluCode.h"
|
2016-03-28 15:09:54 +02:00
|
|
|
#include "LanaiInstrInfo.h"
|
|
|
|
#include "LanaiSubtarget.h"
|
|
|
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
|
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
|
|
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
|
|
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
|
|
|
#include "llvm/IR/Function.h"
|
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
|
|
|
// Determines the size of the frame and maximum call frame size.
|
|
|
|
void LanaiFrameLowering::determineFrameLayout(MachineFunction &MF) const {
|
2016-07-28 20:40:00 +02:00
|
|
|
MachineFrameInfo &MFI = MF.getFrameInfo();
|
2016-03-28 15:09:54 +02:00
|
|
|
const LanaiRegisterInfo *LRI = STI.getRegisterInfo();
|
|
|
|
|
|
|
|
// Get the number of bytes to allocate from the FrameInfo.
|
2016-07-28 20:40:00 +02:00
|
|
|
unsigned FrameSize = MFI.getStackSize();
|
2016-03-28 15:09:54 +02:00
|
|
|
|
|
|
|
// Get the alignment.
|
[Alignment][NFC] Deprecate getMaxAlignment
Summary:
This is patch is part of a series to introduce an Alignment type.
See this thread for context: http://lists.llvm.org/pipermail/llvm-dev/2019-July/133851.html
See this patch for the introduction of the type: https://reviews.llvm.org/D64790
Reviewers: courbet
Subscribers: jholewinski, arsenm, dschuff, jyknight, sdardis, nemanjai, jvesely, nhaehnle, sbc100, jgravelle-google, hiraditya, aheejin, kbarton, fedor.sergeev, asb, rbar, johnrusso, simoncook, sabuasal, niosHD, jrtc27, MaskRay, zzheng, edward-jones, atanasyan, rogfer01, MartinMosbeck, brucehoult, the_o, PkmX, jocewei, Jim, lenary, s.egerton, pzheng, sameer.abuasal, apazos, luismarques, kerbowa, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D76348
2020-03-18 10:50:38 +01:00
|
|
|
Align StackAlign =
|
|
|
|
LRI->needsStackRealignment(MF) ? MFI.getMaxAlign() : getStackAlign();
|
2016-03-28 15:09:54 +02:00
|
|
|
|
|
|
|
// Get the maximum call frame size of all the calls.
|
2016-07-28 20:40:00 +02:00
|
|
|
unsigned MaxCallFrameSize = MFI.getMaxCallFrameSize();
|
2016-03-28 15:09:54 +02:00
|
|
|
|
|
|
|
// If we have dynamic alloca then MaxCallFrameSize needs to be aligned so
|
|
|
|
// that allocations will be aligned.
|
2016-07-28 20:40:00 +02:00
|
|
|
if (MFI.hasVarSizedObjects())
|
2016-03-28 15:09:54 +02:00
|
|
|
MaxCallFrameSize = alignTo(MaxCallFrameSize, StackAlign);
|
|
|
|
|
|
|
|
// Update maximum call frame size.
|
2016-07-28 20:40:00 +02:00
|
|
|
MFI.setMaxCallFrameSize(MaxCallFrameSize);
|
2016-03-28 15:09:54 +02:00
|
|
|
|
|
|
|
// Include call frame size in total.
|
2016-07-28 20:40:00 +02:00
|
|
|
if (!(hasReservedCallFrame(MF) && MFI.adjustsStack()))
|
2016-03-28 15:09:54 +02:00
|
|
|
FrameSize += MaxCallFrameSize;
|
|
|
|
|
|
|
|
// Make sure the frame is aligned.
|
|
|
|
FrameSize = alignTo(FrameSize, StackAlign);
|
|
|
|
|
|
|
|
// Update frame info.
|
2016-07-28 20:40:00 +02:00
|
|
|
MFI.setStackSize(FrameSize);
|
2016-03-28 15:09:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Iterates through each basic block in a machine function and replaces
|
|
|
|
// ADJDYNALLOC pseudo instructions with a Lanai:ADDI with the
|
|
|
|
// maximum call frame size as the immediate.
|
|
|
|
void LanaiFrameLowering::replaceAdjDynAllocPseudo(MachineFunction &MF) const {
|
|
|
|
const LanaiInstrInfo &LII =
|
|
|
|
*static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
|
2016-07-28 20:40:00 +02:00
|
|
|
unsigned MaxCallFrameSize = MF.getFrameInfo().getMaxCallFrameSize();
|
2016-03-28 15:09:54 +02:00
|
|
|
|
|
|
|
for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); MBB != E;
|
|
|
|
++MBB) {
|
|
|
|
MachineBasicBlock::iterator MBBI = MBB->begin();
|
|
|
|
while (MBBI != MBB->end()) {
|
2016-07-09 00:11:30 +02:00
|
|
|
MachineInstr &MI = *MBBI++;
|
|
|
|
if (MI.getOpcode() == Lanai::ADJDYNALLOC) {
|
|
|
|
DebugLoc DL = MI.getDebugLoc();
|
Apply llvm-prefer-register-over-unsigned from clang-tidy to LLVM
Summary:
This clang-tidy check is looking for unsigned integer variables whose initializer
starts with an implicit cast from llvm::Register and changes the type of the
variable to llvm::Register (dropping the llvm:: where possible).
Partial reverts in:
X86FrameLowering.cpp - Some functions return unsigned and arguably should be MCRegister
X86FixupLEAs.cpp - Some functions return unsigned and arguably should be MCRegister
X86FrameLowering.cpp - Some functions return unsigned and arguably should be MCRegister
HexagonBitSimplify.cpp - Function takes BitTracker::RegisterRef which appears to be unsigned&
MachineVerifier.cpp - Ambiguous operator==() given MCRegister and const Register
PPCFastISel.cpp - No Register::operator-=()
PeepholeOptimizer.cpp - TargetInstrInfo::optimizeLoadInstr() takes an unsigned&
MachineTraceMetrics.cpp - MachineTraceMetrics lacks a suitable constructor
Manual fixups in:
ARMFastISel.cpp - ARMEmitLoad() now takes a Register& instead of unsigned&
HexagonSplitDouble.cpp - Ternary operator was ambiguous between unsigned/Register
HexagonConstExtenders.cpp - Has a local class named Register, used llvm::Register instead of Register.
PPCFastISel.cpp - PPCEmitLoad() now takes a Register& instead of unsigned&
Depends on D65919
Reviewers: arsenm, bogner, craig.topper, RKSimon
Reviewed By: arsenm
Subscribers: RKSimon, craig.topper, lenary, aemerson, wuzish, jholewinski, MatzeB, qcolombet, dschuff, jyknight, dylanmckay, sdardis, nemanjai, jvesely, wdng, nhaehnle, sbc100, jgravelle-google, kristof.beyls, hiraditya, aheejin, kbarton, fedor.sergeev, javed.absar, asb, rbar, johnrusso, simoncook, apazos, sabuasal, niosHD, jrtc27, MaskRay, zzheng, edward-jones, atanasyan, rogfer01, MartinMosbeck, brucehoult, the_o, tpr, PkmX, jocewei, jsji, Petar.Avramovic, asbirlea, Jim, s.egerton, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D65962
llvm-svn: 369041
2019-08-15 21:22:08 +02:00
|
|
|
Register Dst = MI.getOperand(0).getReg();
|
|
|
|
Register Src = MI.getOperand(1).getReg();
|
2016-03-28 15:09:54 +02:00
|
|
|
|
|
|
|
BuildMI(*MBB, MI, DL, LII.get(Lanai::ADD_I_LO), Dst)
|
|
|
|
.addReg(Src)
|
|
|
|
.addImm(MaxCallFrameSize);
|
2016-07-09 00:11:30 +02:00
|
|
|
MI.eraseFromParent();
|
2016-03-28 15:09:54 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generates the following sequence for function entry:
|
|
|
|
// st %fp,-4[*%sp] !push old FP
|
|
|
|
// add %sp,8,%fp !generate new FP
|
|
|
|
// sub %sp,0x4,%sp !allocate stack space (as needed)
|
|
|
|
void LanaiFrameLowering::emitPrologue(MachineFunction &MF,
|
|
|
|
MachineBasicBlock &MBB) const {
|
|
|
|
assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
|
|
|
|
|
2016-07-28 20:40:00 +02:00
|
|
|
MachineFrameInfo &MFI = MF.getFrameInfo();
|
2016-03-28 15:09:54 +02:00
|
|
|
const LanaiInstrInfo &LII =
|
|
|
|
*static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
|
|
|
|
MachineBasicBlock::iterator MBBI = MBB.begin();
|
|
|
|
|
|
|
|
// Debug location must be unknown since the first debug location is used
|
|
|
|
// to determine the end of the prologue.
|
|
|
|
DebugLoc DL;
|
|
|
|
|
|
|
|
// Determine the correct frame layout
|
|
|
|
determineFrameLayout(MF);
|
|
|
|
|
|
|
|
// FIXME: This appears to be overallocating. Needs investigation.
|
|
|
|
// Get the number of bytes to allocate from the FrameInfo.
|
2016-07-28 20:40:00 +02:00
|
|
|
unsigned StackSize = MFI.getStackSize();
|
2016-03-28 15:09:54 +02:00
|
|
|
|
|
|
|
// Push old FP
|
|
|
|
// st %fp,-4[*%sp]
|
|
|
|
BuildMI(MBB, MBBI, DL, LII.get(Lanai::SW_RI))
|
|
|
|
.addReg(Lanai::FP)
|
|
|
|
.addReg(Lanai::SP)
|
|
|
|
.addImm(-4)
|
|
|
|
.addImm(LPAC::makePreOp(LPAC::ADD))
|
|
|
|
.setMIFlag(MachineInstr::FrameSetup);
|
|
|
|
|
|
|
|
// Generate new FP
|
|
|
|
// add %sp,8,%fp
|
|
|
|
BuildMI(MBB, MBBI, DL, LII.get(Lanai::ADD_I_LO), Lanai::FP)
|
|
|
|
.addReg(Lanai::SP)
|
|
|
|
.addImm(8)
|
|
|
|
.setMIFlag(MachineInstr::FrameSetup);
|
|
|
|
|
|
|
|
// Allocate space on the stack if needed
|
|
|
|
// sub %sp,StackSize,%sp
|
|
|
|
if (StackSize != 0) {
|
|
|
|
BuildMI(MBB, MBBI, DL, LII.get(Lanai::SUB_I_LO), Lanai::SP)
|
|
|
|
.addReg(Lanai::SP)
|
|
|
|
.addImm(StackSize)
|
|
|
|
.setMIFlag(MachineInstr::FrameSetup);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Replace ADJDYNANALLOC
|
2016-07-28 20:40:00 +02:00
|
|
|
if (MFI.hasVarSizedObjects())
|
2016-03-28 15:09:54 +02:00
|
|
|
replaceAdjDynAllocPseudo(MF);
|
|
|
|
}
|
|
|
|
|
2016-03-31 20:33:38 +02:00
|
|
|
MachineBasicBlock::iterator LanaiFrameLowering::eliminateCallFramePseudoInstr(
|
2016-07-16 00:38:32 +02:00
|
|
|
MachineFunction & /*MF*/, MachineBasicBlock &MBB,
|
2016-03-28 15:09:54 +02:00
|
|
|
MachineBasicBlock::iterator I) const {
|
|
|
|
// Discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
|
2016-03-31 20:33:38 +02:00
|
|
|
return MBB.erase(I);
|
2016-03-28 15:09:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// The function epilogue should not depend on the current stack pointer!
|
|
|
|
// It should use the frame pointer only. This is mandatory because
|
|
|
|
// of alloca; we also take advantage of it to omit stack adjustments
|
|
|
|
// before returning.
|
|
|
|
//
|
|
|
|
// Note that when we go to restore the preserved register values we must
|
|
|
|
// not try to address their slots by using offsets from the stack pointer.
|
|
|
|
// That's because the stack pointer may have been moved during the function
|
|
|
|
// execution due to a call to alloca(). Rather, we must restore all
|
|
|
|
// preserved registers via offsets from the frame pointer value.
|
|
|
|
//
|
|
|
|
// Note also that when the current frame is being "popped" (by adjusting
|
|
|
|
// the value of the stack pointer) on function exit, we must (for the
|
|
|
|
// sake of alloca) set the new value of the stack pointer based upon
|
|
|
|
// the current value of the frame pointer. We can't just add what we
|
|
|
|
// believe to be the (static) frame size to the stack pointer because
|
|
|
|
// if we did that, and alloca() had been called during this function,
|
|
|
|
// we would end up returning *without* having fully deallocated all of
|
|
|
|
// the space grabbed by alloca. If that happened, and a function
|
|
|
|
// containing one or more alloca() calls was called over and over again,
|
|
|
|
// then the stack would grow without limit!
|
|
|
|
//
|
|
|
|
// RET is lowered to
|
|
|
|
// ld -4[%fp],%pc # modify %pc (two delay slots)
|
|
|
|
// as the return address is in the stack frame and mov to pc is allowed.
|
|
|
|
// emitEpilogue emits
|
|
|
|
// mov %fp,%sp # restore the stack pointer
|
|
|
|
// ld -8[%fp],%fp # restore the caller's frame pointer
|
|
|
|
// before RET and the delay slot filler will move RET such that these
|
|
|
|
// instructions execute in the delay slots of the load to PC.
|
2016-07-16 00:38:32 +02:00
|
|
|
void LanaiFrameLowering::emitEpilogue(MachineFunction & /*MF*/,
|
2016-03-28 15:09:54 +02:00
|
|
|
MachineBasicBlock &MBB) const {
|
|
|
|
MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
|
|
|
|
const LanaiInstrInfo &LII =
|
|
|
|
*static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
|
|
|
|
DebugLoc DL = MBBI->getDebugLoc();
|
|
|
|
|
|
|
|
// Restore the stack pointer using the callee's frame pointer value.
|
|
|
|
BuildMI(MBB, MBBI, DL, LII.get(Lanai::ADD_I_LO), Lanai::SP)
|
|
|
|
.addReg(Lanai::FP)
|
|
|
|
.addImm(0);
|
|
|
|
|
|
|
|
// Restore the frame pointer from the stack.
|
|
|
|
BuildMI(MBB, MBBI, DL, LII.get(Lanai::LDW_RI), Lanai::FP)
|
|
|
|
.addReg(Lanai::FP)
|
|
|
|
.addImm(-8)
|
|
|
|
.addImm(LPAC::ADD);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LanaiFrameLowering::determineCalleeSaves(MachineFunction &MF,
|
|
|
|
BitVector &SavedRegs,
|
|
|
|
RegScavenger *RS) const {
|
|
|
|
TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
|
|
|
|
|
2016-07-28 20:40:00 +02:00
|
|
|
MachineFrameInfo &MFI = MF.getFrameInfo();
|
2016-03-28 15:09:54 +02:00
|
|
|
const LanaiRegisterInfo *LRI =
|
|
|
|
static_cast<const LanaiRegisterInfo *>(STI.getRegisterInfo());
|
|
|
|
int Offset = -4;
|
|
|
|
|
|
|
|
// Reserve 4 bytes for the saved RCA
|
2016-07-28 20:40:00 +02:00
|
|
|
MFI.CreateFixedObject(4, Offset, true);
|
2016-03-28 15:09:54 +02:00
|
|
|
Offset -= 4;
|
|
|
|
|
|
|
|
// Reserve 4 bytes for the saved FP
|
2016-07-28 20:40:00 +02:00
|
|
|
MFI.CreateFixedObject(4, Offset, true);
|
2016-03-28 15:09:54 +02:00
|
|
|
Offset -= 4;
|
|
|
|
|
|
|
|
if (LRI->hasBasePointer(MF)) {
|
2016-07-28 20:40:00 +02:00
|
|
|
MFI.CreateFixedObject(4, Offset, true);
|
2016-03-28 15:09:54 +02:00
|
|
|
SavedRegs.reset(LRI->getBaseRegister());
|
|
|
|
}
|
|
|
|
}
|