mirror of
https://github.com/RPCS3/llvm.git
synced 2025-05-13 08:56:04 +00:00

Note: I do not implement a base pointer, so it's still impossible to have dynamic realignment AND dynamic alloca in the same function. This also moves the code for determining the frame index reference into getFrameIndexReference, where it belongs, instead of inline in eliminateFrameIndex. [Begin long-winded screed] Now, stack realignment for Sparc is actually a silly thing to support, because the Sparc ABI has no need for it -- unlike the situation on x86, the stack is ALWAYS aligned to the required alignment for the CPU instructions: 8 bytes on sparcv8, and 16 bytes on sparcv9. However, LLVM unfortunately implements user-specified overalignment using stack realignment support, so for now, I'm going to go along with that tradition. GCC instead treats objects which have alignment specification greater than the maximum CPU-required alignment for the target as a separate block of stack memory, with their own virtual base pointer (which gets aligned). Doing it that way avoids needing to implement per-target support for stack realignment, except for the targets which *actually* have an ABI-specified stack alignment which is too small for the CPU's requirements. Further unfortunately in LLVM, the default canRealignStack for all targets effectively returns true, despite that implementing that is something a target needs to do specifically. So, the previous behavior on Sparc was to silently ignore the user's specified stack alignment. Ugh. Yet MORE unfortunate, if a target actually does return false from canRealignStack, that also causes the user-specified alignment to be *silently ignored*, rather than emitting an error. (I started looking into fixing that last, but it broke a bunch of tests, because LLVM actually *depends* on having it silently ignored: some architectures (e.g. non-linux i386) have smaller stack alignment than spilled-register alignment. But, the fact that a register needs spilling is not known until within the register allocator. And by that point, the decision to not reserve the frame pointer has been frozen in place. And without a frame pointer, stack realignment is not possible. So, canRealignStack() returns false, and needsStackRealignment() then returns false, assuming everyone can just go on their merry way assuming the alignment requirements were probably just suggestions after-all. Sigh...) Differential Revision: http://reviews.llvm.org/D12208 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@245668 91177308-0d34-0410-b5e6-96231b3b80d8
63 lines
2.1 KiB
C++
63 lines
2.1 KiB
C++
//===-- SparcFrameLowering.h - Define frame lowering for Sparc --*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
//
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_LIB_TARGET_SPARC_SPARCFRAMELOWERING_H
|
|
#define LLVM_LIB_TARGET_SPARC_SPARCFRAMELOWERING_H
|
|
|
|
#include "Sparc.h"
|
|
#include "llvm/Target/TargetFrameLowering.h"
|
|
|
|
namespace llvm {
|
|
|
|
class SparcSubtarget;
|
|
class SparcFrameLowering : public TargetFrameLowering {
|
|
public:
|
|
explicit SparcFrameLowering(const SparcSubtarget &ST);
|
|
|
|
/// emitProlog/emitEpilog - These methods insert prolog and epilog code into
|
|
/// the function.
|
|
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
|
|
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
|
|
|
|
void
|
|
eliminateCallFramePseudoInstr(MachineFunction &MF,
|
|
MachineBasicBlock &MBB,
|
|
MachineBasicBlock::iterator I) const override;
|
|
|
|
bool hasReservedCallFrame(const MachineFunction &MF) const override;
|
|
bool hasFP(const MachineFunction &MF) const override;
|
|
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
|
|
RegScavenger *RS = nullptr) const override;
|
|
|
|
int getFrameIndexReference(const MachineFunction &MF, int FI,
|
|
unsigned &FrameReg) const override;
|
|
private:
|
|
// Remap input registers to output registers for leaf procedure.
|
|
void remapRegsForLeafProc(MachineFunction &MF) const;
|
|
|
|
// Returns true if MF is a leaf procedure.
|
|
bool isLeafProc(MachineFunction &MF) const;
|
|
|
|
|
|
// Emits code for adjusting SP in function prologue/epilogue.
|
|
void emitSPAdjustment(MachineFunction &MF,
|
|
MachineBasicBlock &MBB,
|
|
MachineBasicBlock::iterator MBBI,
|
|
int NumBytes, unsigned ADDrr, unsigned ADDri) const;
|
|
|
|
};
|
|
|
|
} // End llvm namespace
|
|
|
|
#endif
|