1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-22 12:33:33 +02:00
llvm-mirror/lib/Target/RISCV/RISCVRegisterInfo.cpp
Alex Bradbury 1a0155bc19 [RISCV] Set isReMaterializable on ADDI and LUI instructions
The isReMaterlizable flag is somewhat confusing, unlike most other instruction 
flags it is currently interpreted as a hint (mightBeRematerializable would be 
a better name). While LUI is always rematerialisable, for an instruction like 
ADDI it depends on its operands. TargetInstrInfo::isTriviallyReMaterializable 
will call TargetInstrInfo::isReallyTriviallyReMaterializable, which in turn 
calls TargetInstrInfo::isReallyTriviallyReMaterializableGeneric. We rely on 
the logic in the latter to pick out instances of ADDI that really are 
rematerializable.

The isReMaterializable flag does make a difference on a variety of test 
programs. The recently committed remat.ll test case demonstrates how stack 
usage is reduce and a unnecessary lw/sw can be removed. Stack usage in the 
Proc0 function in dhrystone reduces from 192 bytes to 112 bytes.

For the sake of completeness, this patch also implements 
RISCVRegisterInfo::isConstantPhysReg. Although this is called from a number of 
places, it doesn't seem to result in different codegen for any programs I've 
thrown at it. However, it is called in the rematerialisation codepath and it 
seems sensible to implement something correct here.

Differential Revision: https://reviews.llvm.org/D46182

llvm-svn: 332617
2018-05-17 15:51:37 +00:00

115 lines
3.9 KiB
C++

//===-- RISCVRegisterInfo.cpp - RISCV Register Information ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the RISCV implementation of the TargetRegisterInfo class.
//
//===----------------------------------------------------------------------===//
#include "RISCVRegisterInfo.h"
#include "RISCV.h"
#include "RISCVSubtarget.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/Support/ErrorHandling.h"
#define GET_REGINFO_TARGET_DESC
#include "RISCVGenRegisterInfo.inc"
using namespace llvm;
RISCVRegisterInfo::RISCVRegisterInfo(unsigned HwMode)
: RISCVGenRegisterInfo(RISCV::X1, /*DwarfFlavour*/0, /*EHFlavor*/0,
/*PC*/0, HwMode) {}
const MCPhysReg *
RISCVRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
return CSR_SaveList;
}
BitVector RISCVRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
BitVector Reserved(getNumRegs());
// Use markSuperRegs to ensure any register aliases are also reserved
markSuperRegs(Reserved, RISCV::X0); // zero
markSuperRegs(Reserved, RISCV::X1); // ra
markSuperRegs(Reserved, RISCV::X2); // sp
markSuperRegs(Reserved, RISCV::X3); // gp
markSuperRegs(Reserved, RISCV::X4); // tp
markSuperRegs(Reserved, RISCV::X8); // fp
assert(checkAllSuperRegsMarked(Reserved));
return Reserved;
}
bool RISCVRegisterInfo::isConstantPhysReg(unsigned PhysReg) const {
return PhysReg == RISCV::X0;
}
const uint32_t *RISCVRegisterInfo::getNoPreservedMask() const {
return CSR_NoRegs_RegMask;
}
void RISCVRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, unsigned FIOperandNum,
RegScavenger *RS) const {
assert(SPAdj == 0 && "Unexpected non-zero SPAdj value");
MachineInstr &MI = *II;
MachineFunction &MF = *MI.getParent()->getParent();
MachineRegisterInfo &MRI = MF.getRegInfo();
const RISCVInstrInfo *TII = MF.getSubtarget<RISCVSubtarget>().getInstrInfo();
DebugLoc DL = MI.getDebugLoc();
int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
unsigned FrameReg;
int Offset =
getFrameLowering(MF)->getFrameIndexReference(MF, FrameIndex, FrameReg) +
MI.getOperand(FIOperandNum + 1).getImm();
if (!isInt<32>(Offset)) {
report_fatal_error(
"Frame offsets outside of the signed 32-bit range not supported");
}
MachineBasicBlock &MBB = *MI.getParent();
bool FrameRegIsKill = false;
if (!isInt<12>(Offset)) {
assert(isInt<32>(Offset) && "Int32 expected");
// The offset won't fit in an immediate, so use a scratch register instead
// Modify Offset and FrameReg appropriately
unsigned ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
TII->movImm32(MBB, II, DL, ScratchReg, Offset);
BuildMI(MBB, II, DL, TII->get(RISCV::ADD), ScratchReg)
.addReg(FrameReg)
.addReg(ScratchReg, RegState::Kill);
Offset = 0;
FrameReg = ScratchReg;
FrameRegIsKill = true;
}
MI.getOperand(FIOperandNum)
.ChangeToRegister(FrameReg, false, false, FrameRegIsKill);
MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
}
unsigned RISCVRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
const TargetFrameLowering *TFI = getFrameLowering(MF);
return TFI->hasFP(MF) ? RISCV::X8 : RISCV::X2;
}
const uint32_t *
RISCVRegisterInfo::getCallPreservedMask(const MachineFunction & /*MF*/,
CallingConv::ID /*CC*/) const {
return CSR_RegMask;
}