mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-03 13:31:05 +00:00
[PowerPC] Put PPCVSXCopy into its own source file
PPCInstrInfo.cpp has ended up containing several small MI-level passes, and this is making the file harder to read than necessary. Split out PPCVSXCopy into its own source file. NFC. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@227771 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
dad591a435
commit
2a9d9584b4
@ -30,6 +30,7 @@ add_llvm_target(PowerPCCodeGen
|
||||
PPCTargetObjectFile.cpp
|
||||
PPCTargetTransformInfo.cpp
|
||||
PPCSelectionDAGInfo.cpp
|
||||
PPCVSXCopy.cpp
|
||||
PPCVSXFMAMutate.cpp
|
||||
)
|
||||
|
||||
|
@ -1605,145 +1605,6 @@ unsigned PPCInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
|
||||
}
|
||||
}
|
||||
|
||||
#undef DEBUG_TYPE
|
||||
#define DEBUG_TYPE "ppc-vsx-copy"
|
||||
|
||||
namespace llvm {
|
||||
void initializePPCVSXCopyPass(PassRegistry&);
|
||||
}
|
||||
|
||||
namespace {
|
||||
// PPCVSXCopy pass - For copies between VSX registers and non-VSX registers
|
||||
// (Altivec and scalar floating-point registers), we need to transform the
|
||||
// copies into subregister copies with other restrictions.
|
||||
struct PPCVSXCopy : public MachineFunctionPass {
|
||||
static char ID;
|
||||
PPCVSXCopy() : MachineFunctionPass(ID) {
|
||||
initializePPCVSXCopyPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
const TargetInstrInfo *TII;
|
||||
|
||||
bool IsRegInClass(unsigned Reg, const TargetRegisterClass *RC,
|
||||
MachineRegisterInfo &MRI) {
|
||||
if (TargetRegisterInfo::isVirtualRegister(Reg)) {
|
||||
return RC->hasSubClassEq(MRI.getRegClass(Reg));
|
||||
} else if (RC->contains(Reg)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsVSReg(unsigned Reg, MachineRegisterInfo &MRI) {
|
||||
return IsRegInClass(Reg, &PPC::VSRCRegClass, MRI);
|
||||
}
|
||||
|
||||
bool IsVRReg(unsigned Reg, MachineRegisterInfo &MRI) {
|
||||
return IsRegInClass(Reg, &PPC::VRRCRegClass, MRI);
|
||||
}
|
||||
|
||||
bool IsF8Reg(unsigned Reg, MachineRegisterInfo &MRI) {
|
||||
return IsRegInClass(Reg, &PPC::F8RCRegClass, MRI);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool processBlock(MachineBasicBlock &MBB) {
|
||||
bool Changed = false;
|
||||
|
||||
MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
|
||||
for (MachineBasicBlock::iterator I = MBB.begin(), IE = MBB.end();
|
||||
I != IE; ++I) {
|
||||
MachineInstr *MI = I;
|
||||
if (!MI->isFullCopy())
|
||||
continue;
|
||||
|
||||
MachineOperand &DstMO = MI->getOperand(0);
|
||||
MachineOperand &SrcMO = MI->getOperand(1);
|
||||
|
||||
if ( IsVSReg(DstMO.getReg(), MRI) &&
|
||||
!IsVSReg(SrcMO.getReg(), MRI)) {
|
||||
// This is a copy *to* a VSX register from a non-VSX register.
|
||||
Changed = true;
|
||||
|
||||
const TargetRegisterClass *SrcRC =
|
||||
IsVRReg(SrcMO.getReg(), MRI) ? &PPC::VSHRCRegClass :
|
||||
&PPC::VSLRCRegClass;
|
||||
assert((IsF8Reg(SrcMO.getReg(), MRI) ||
|
||||
IsVRReg(SrcMO.getReg(), MRI)) &&
|
||||
"Unknown source for a VSX copy");
|
||||
|
||||
unsigned NewVReg = MRI.createVirtualRegister(SrcRC);
|
||||
BuildMI(MBB, MI, MI->getDebugLoc(),
|
||||
TII->get(TargetOpcode::SUBREG_TO_REG), NewVReg)
|
||||
.addImm(1) // add 1, not 0, because there is no implicit clearing
|
||||
// of the high bits.
|
||||
.addOperand(SrcMO)
|
||||
.addImm(IsVRReg(SrcMO.getReg(), MRI) ? PPC::sub_128 :
|
||||
PPC::sub_64);
|
||||
|
||||
// The source of the original copy is now the new virtual register.
|
||||
SrcMO.setReg(NewVReg);
|
||||
} else if (!IsVSReg(DstMO.getReg(), MRI) &&
|
||||
IsVSReg(SrcMO.getReg(), MRI)) {
|
||||
// This is a copy *from* a VSX register to a non-VSX register.
|
||||
Changed = true;
|
||||
|
||||
const TargetRegisterClass *DstRC =
|
||||
IsVRReg(DstMO.getReg(), MRI) ? &PPC::VSHRCRegClass :
|
||||
&PPC::VSLRCRegClass;
|
||||
assert((IsF8Reg(DstMO.getReg(), MRI) ||
|
||||
IsVRReg(DstMO.getReg(), MRI)) &&
|
||||
"Unknown destination for a VSX copy");
|
||||
|
||||
// Copy the VSX value into a new VSX register of the correct subclass.
|
||||
unsigned NewVReg = MRI.createVirtualRegister(DstRC);
|
||||
BuildMI(MBB, MI, MI->getDebugLoc(),
|
||||
TII->get(TargetOpcode::COPY), NewVReg)
|
||||
.addOperand(SrcMO);
|
||||
|
||||
// Transform the original copy into a subregister extraction copy.
|
||||
SrcMO.setReg(NewVReg);
|
||||
SrcMO.setSubReg(IsVRReg(DstMO.getReg(), MRI) ? PPC::sub_128 :
|
||||
PPC::sub_64);
|
||||
}
|
||||
}
|
||||
|
||||
return Changed;
|
||||
}
|
||||
|
||||
public:
|
||||
bool runOnMachineFunction(MachineFunction &MF) override {
|
||||
// If we don't have VSX on the subtarget, don't do anything.
|
||||
const PPCSubtarget &STI = MF.getSubtarget<PPCSubtarget>();
|
||||
if (!STI.hasVSX())
|
||||
return false;
|
||||
TII = STI.getInstrInfo();
|
||||
|
||||
bool Changed = false;
|
||||
|
||||
for (MachineFunction::iterator I = MF.begin(); I != MF.end();) {
|
||||
MachineBasicBlock &B = *I++;
|
||||
if (processBlock(B))
|
||||
Changed = true;
|
||||
}
|
||||
|
||||
return Changed;
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
MachineFunctionPass::getAnalysisUsage(AU);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
INITIALIZE_PASS(PPCVSXCopy, DEBUG_TYPE,
|
||||
"PowerPC VSX Copy Legalization", false, false)
|
||||
|
||||
char PPCVSXCopy::ID = 0;
|
||||
FunctionPass*
|
||||
llvm::createPPCVSXCopyPass() { return new PPCVSXCopy(); }
|
||||
|
||||
#undef DEBUG_TYPE
|
||||
#define DEBUG_TYPE "ppc-early-ret"
|
||||
STATISTIC(NumBCLR, "Number of early conditional returns");
|
||||
|
176
lib/Target/PowerPC/PPCVSXCopy.cpp
Normal file
176
lib/Target/PowerPC/PPCVSXCopy.cpp
Normal file
@ -0,0 +1,176 @@
|
||||
//===-------------- PPCVSXCopy.cpp - VSX Copy Legalization ----------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// A pass which deals with the complexity of generating legal VSX register
|
||||
// copies to/from register classes which partially overlap with the VSX
|
||||
// register file.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "PPCInstrInfo.h"
|
||||
#include "MCTargetDesc/PPCPredicates.h"
|
||||
#include "PPC.h"
|
||||
#include "PPCHazardRecognizers.h"
|
||||
#include "PPCInstrBuilder.h"
|
||||
#include "PPCMachineFunctionInfo.h"
|
||||
#include "PPCTargetMachine.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineMemOperand.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "ppc-vsx-copy"
|
||||
|
||||
namespace llvm {
|
||||
void initializePPCVSXCopyPass(PassRegistry&);
|
||||
}
|
||||
|
||||
namespace {
|
||||
// PPCVSXCopy pass - For copies between VSX registers and non-VSX registers
|
||||
// (Altivec and scalar floating-point registers), we need to transform the
|
||||
// copies into subregister copies with other restrictions.
|
||||
struct PPCVSXCopy : public MachineFunctionPass {
|
||||
static char ID;
|
||||
PPCVSXCopy() : MachineFunctionPass(ID) {
|
||||
initializePPCVSXCopyPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
const TargetInstrInfo *TII;
|
||||
|
||||
bool IsRegInClass(unsigned Reg, const TargetRegisterClass *RC,
|
||||
MachineRegisterInfo &MRI) {
|
||||
if (TargetRegisterInfo::isVirtualRegister(Reg)) {
|
||||
return RC->hasSubClassEq(MRI.getRegClass(Reg));
|
||||
} else if (RC->contains(Reg)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsVSReg(unsigned Reg, MachineRegisterInfo &MRI) {
|
||||
return IsRegInClass(Reg, &PPC::VSRCRegClass, MRI);
|
||||
}
|
||||
|
||||
bool IsVRReg(unsigned Reg, MachineRegisterInfo &MRI) {
|
||||
return IsRegInClass(Reg, &PPC::VRRCRegClass, MRI);
|
||||
}
|
||||
|
||||
bool IsF8Reg(unsigned Reg, MachineRegisterInfo &MRI) {
|
||||
return IsRegInClass(Reg, &PPC::F8RCRegClass, MRI);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool processBlock(MachineBasicBlock &MBB) {
|
||||
bool Changed = false;
|
||||
|
||||
MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
|
||||
for (MachineBasicBlock::iterator I = MBB.begin(), IE = MBB.end();
|
||||
I != IE; ++I) {
|
||||
MachineInstr *MI = I;
|
||||
if (!MI->isFullCopy())
|
||||
continue;
|
||||
|
||||
MachineOperand &DstMO = MI->getOperand(0);
|
||||
MachineOperand &SrcMO = MI->getOperand(1);
|
||||
|
||||
if ( IsVSReg(DstMO.getReg(), MRI) &&
|
||||
!IsVSReg(SrcMO.getReg(), MRI)) {
|
||||
// This is a copy *to* a VSX register from a non-VSX register.
|
||||
Changed = true;
|
||||
|
||||
const TargetRegisterClass *SrcRC =
|
||||
IsVRReg(SrcMO.getReg(), MRI) ? &PPC::VSHRCRegClass :
|
||||
&PPC::VSLRCRegClass;
|
||||
assert((IsF8Reg(SrcMO.getReg(), MRI) ||
|
||||
IsVRReg(SrcMO.getReg(), MRI)) &&
|
||||
"Unknown source for a VSX copy");
|
||||
|
||||
unsigned NewVReg = MRI.createVirtualRegister(SrcRC);
|
||||
BuildMI(MBB, MI, MI->getDebugLoc(),
|
||||
TII->get(TargetOpcode::SUBREG_TO_REG), NewVReg)
|
||||
.addImm(1) // add 1, not 0, because there is no implicit clearing
|
||||
// of the high bits.
|
||||
.addOperand(SrcMO)
|
||||
.addImm(IsVRReg(SrcMO.getReg(), MRI) ? PPC::sub_128 :
|
||||
PPC::sub_64);
|
||||
|
||||
// The source of the original copy is now the new virtual register.
|
||||
SrcMO.setReg(NewVReg);
|
||||
} else if (!IsVSReg(DstMO.getReg(), MRI) &&
|
||||
IsVSReg(SrcMO.getReg(), MRI)) {
|
||||
// This is a copy *from* a VSX register to a non-VSX register.
|
||||
Changed = true;
|
||||
|
||||
const TargetRegisterClass *DstRC =
|
||||
IsVRReg(DstMO.getReg(), MRI) ? &PPC::VSHRCRegClass :
|
||||
&PPC::VSLRCRegClass;
|
||||
assert((IsF8Reg(DstMO.getReg(), MRI) ||
|
||||
IsVRReg(DstMO.getReg(), MRI)) &&
|
||||
"Unknown destination for a VSX copy");
|
||||
|
||||
// Copy the VSX value into a new VSX register of the correct subclass.
|
||||
unsigned NewVReg = MRI.createVirtualRegister(DstRC);
|
||||
BuildMI(MBB, MI, MI->getDebugLoc(),
|
||||
TII->get(TargetOpcode::COPY), NewVReg)
|
||||
.addOperand(SrcMO);
|
||||
|
||||
// Transform the original copy into a subregister extraction copy.
|
||||
SrcMO.setReg(NewVReg);
|
||||
SrcMO.setSubReg(IsVRReg(DstMO.getReg(), MRI) ? PPC::sub_128 :
|
||||
PPC::sub_64);
|
||||
}
|
||||
}
|
||||
|
||||
return Changed;
|
||||
}
|
||||
|
||||
public:
|
||||
bool runOnMachineFunction(MachineFunction &MF) override {
|
||||
// If we don't have VSX on the subtarget, don't do anything.
|
||||
const PPCSubtarget &STI = MF.getSubtarget<PPCSubtarget>();
|
||||
if (!STI.hasVSX())
|
||||
return false;
|
||||
TII = STI.getInstrInfo();
|
||||
|
||||
bool Changed = false;
|
||||
|
||||
for (MachineFunction::iterator I = MF.begin(); I != MF.end();) {
|
||||
MachineBasicBlock &B = *I++;
|
||||
if (processBlock(B))
|
||||
Changed = true;
|
||||
}
|
||||
|
||||
return Changed;
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
MachineFunctionPass::getAnalysisUsage(AU);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
INITIALIZE_PASS(PPCVSXCopy, DEBUG_TYPE,
|
||||
"PowerPC VSX Copy Legalization", false, false)
|
||||
|
||||
char PPCVSXCopy::ID = 0;
|
||||
FunctionPass*
|
||||
llvm::createPPCVSXCopyPass() { return new PPCVSXCopy(); }
|
||||
|
Loading…
Reference in New Issue
Block a user