mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-13 09:33:50 +00:00
Convert Alpha and Mips to use a MachineFunctionInfo subclass to
carry GlobalBaseReg, and GlobalRetAddr too in Alpha's case. This eliminates the need for them to search through the MachineRegisterInfo livein list in order to identify these virtual registers. EmitLiveInCopies is now the only user of the virtual register portion of MachineRegisterInfo's livein data. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72802 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c553462c29
commit
9911405183
@ -185,8 +185,20 @@ namespace {
|
||||
#include "AlphaGenDAGISel.inc"
|
||||
|
||||
private:
|
||||
SDValue getGlobalBaseReg();
|
||||
SDValue getGlobalRetAddr();
|
||||
/// getTargetMachine - Return a reference to the TargetMachine, casted
|
||||
/// to the target-specific type.
|
||||
const AlphaTargetMachine &getTargetMachine() {
|
||||
return static_cast<const AlphaTargetMachine &>(TM);
|
||||
}
|
||||
|
||||
/// getInstrInfo - Return a reference to the TargetInstrInfo, casted
|
||||
/// to the target-specific type.
|
||||
const AlphaInstrInfo *getInstrInfo() {
|
||||
return getTargetMachine().getInstrInfo();
|
||||
}
|
||||
|
||||
SDNode *getGlobalBaseReg();
|
||||
SDNode *getGlobalRetAddr();
|
||||
void SelectCALL(SDValue Op);
|
||||
|
||||
};
|
||||
@ -195,34 +207,18 @@ private:
|
||||
/// getGlobalBaseReg - Output the instructions required to put the
|
||||
/// GOT address into a register.
|
||||
///
|
||||
SDValue AlphaDAGToDAGISel::getGlobalBaseReg() {
|
||||
unsigned GP = 0;
|
||||
for(MachineRegisterInfo::livein_iterator ii = RegInfo->livein_begin(),
|
||||
ee = RegInfo->livein_end(); ii != ee; ++ii)
|
||||
if (ii->first == Alpha::R29) {
|
||||
GP = ii->second;
|
||||
break;
|
||||
}
|
||||
assert(GP && "GOT PTR not in liveins");
|
||||
// FIXME is there anywhere sensible to get a DebugLoc here?
|
||||
return CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
|
||||
DebugLoc::getUnknownLoc(), GP, MVT::i64);
|
||||
SDNode *AlphaDAGToDAGISel::getGlobalBaseReg() {
|
||||
MachineFunction *MF = BB->getParent();
|
||||
unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF);
|
||||
return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode();
|
||||
}
|
||||
|
||||
/// getRASaveReg - Grab the return address
|
||||
/// getGlobalRetAddr - Grab the return address.
|
||||
///
|
||||
SDValue AlphaDAGToDAGISel::getGlobalRetAddr() {
|
||||
unsigned RA = 0;
|
||||
for(MachineRegisterInfo::livein_iterator ii = RegInfo->livein_begin(),
|
||||
ee = RegInfo->livein_end(); ii != ee; ++ii)
|
||||
if (ii->first == Alpha::R26) {
|
||||
RA = ii->second;
|
||||
break;
|
||||
}
|
||||
assert(RA && "RA PTR not in liveins");
|
||||
// FIXME is there anywhere sensible to get a DebugLoc here?
|
||||
return CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
|
||||
DebugLoc::getUnknownLoc(), RA, MVT::i64);
|
||||
SDNode *AlphaDAGToDAGISel::getGlobalRetAddr() {
|
||||
MachineFunction *MF = BB->getParent();
|
||||
unsigned GlobalRetAddr = getInstrInfo()->getGlobalRetAddr(MF);
|
||||
return CurDAG->getRegister(GlobalRetAddr, TLI.getPointerTy()).getNode();
|
||||
}
|
||||
|
||||
/// InstructionSelect - This callback is invoked by
|
||||
@ -256,16 +252,10 @@ SDNode *AlphaDAGToDAGISel::Select(SDValue Op) {
|
||||
CurDAG->getTargetFrameIndex(FI, MVT::i32),
|
||||
getI64Imm(0));
|
||||
}
|
||||
case ISD::GLOBAL_OFFSET_TABLE: {
|
||||
SDValue Result = getGlobalBaseReg();
|
||||
ReplaceUses(Op, Result);
|
||||
return NULL;
|
||||
}
|
||||
case AlphaISD::GlobalRetAddr: {
|
||||
SDValue Result = getGlobalRetAddr();
|
||||
ReplaceUses(Op, Result);
|
||||
return NULL;
|
||||
}
|
||||
case ISD::GLOBAL_OFFSET_TABLE:
|
||||
return getGlobalBaseReg();
|
||||
case AlphaISD::GlobalRetAddr:
|
||||
return getGlobalRetAddr();
|
||||
|
||||
case AlphaISD::DivCall: {
|
||||
SDValue Chain = CurDAG->getEntryNode();
|
||||
@ -315,7 +305,7 @@ SDNode *AlphaDAGToDAGISel::Select(SDValue Op) {
|
||||
ConstantInt *C = ConstantInt::get(Type::Int64Ty, uval);
|
||||
SDValue CPI = CurDAG->getTargetConstantPool(C, MVT::i64);
|
||||
SDNode *Tmp = CurDAG->getTargetNode(Alpha::LDAHr, dl, MVT::i64, CPI,
|
||||
getGlobalBaseReg());
|
||||
SDValue(getGlobalBaseReg(), 0));
|
||||
return CurDAG->SelectNodeTo(N, Alpha::LDQr, MVT::i64, MVT::Other,
|
||||
CPI, SDValue(Tmp, 0), CurDAG->getEntryNode());
|
||||
}
|
||||
@ -503,7 +493,7 @@ void AlphaDAGToDAGISel::SelectCALL(SDValue Op) {
|
||||
// Finally, once everything is in registers to pass to the call, emit the
|
||||
// call itself.
|
||||
if (Addr.getOpcode() == AlphaISD::GPRelLo) {
|
||||
SDValue GOT = getGlobalBaseReg();
|
||||
SDValue GOT = SDValue(getGlobalBaseReg(), 0);
|
||||
Chain = CurDAG->getCopyToReg(Chain, dl, Alpha::R29, GOT, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
Chain = SDValue(CurDAG->getTargetNode(Alpha::BSR, dl, MVT::Other,
|
||||
|
@ -223,9 +223,6 @@ static SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG,
|
||||
SDValue Root = Op.getOperand(0);
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
|
||||
AddLiveIn(MF, Alpha::R29, &Alpha::GPRCRegClass); //GP
|
||||
AddLiveIn(MF, Alpha::R26, &Alpha::GPRCRegClass); //RA
|
||||
|
||||
unsigned args_int[] = {
|
||||
Alpha::R16, Alpha::R17, Alpha::R18, Alpha::R19, Alpha::R20, Alpha::R21};
|
||||
unsigned args_float[] = {
|
||||
|
@ -13,7 +13,9 @@
|
||||
|
||||
#include "Alpha.h"
|
||||
#include "AlphaInstrInfo.h"
|
||||
#include "AlphaMachineFunctionInfo.h"
|
||||
#include "AlphaGenInstrInfo.inc"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
@ -448,3 +450,54 @@ ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// getGlobalBaseReg - Return a virtual register initialized with the
|
||||
/// the global base register value. Output instructions required to
|
||||
/// initialize the register in the function entry block, if necessary.
|
||||
///
|
||||
unsigned AlphaInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
|
||||
AlphaMachineFunctionInfo *AlphaFI = MF->getInfo<AlphaMachineFunctionInfo>();
|
||||
unsigned GlobalBaseReg = AlphaFI->getGlobalBaseReg();
|
||||
if (GlobalBaseReg != 0)
|
||||
return GlobalBaseReg;
|
||||
|
||||
// Insert the set of GlobalBaseReg into the first MBB of the function
|
||||
MachineBasicBlock &FirstMBB = MF->front();
|
||||
MachineBasicBlock::iterator MBBI = FirstMBB.begin();
|
||||
MachineRegisterInfo &RegInfo = MF->getRegInfo();
|
||||
const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
|
||||
|
||||
GlobalBaseReg = RegInfo.createVirtualRegister(&Alpha::GPRCRegClass);
|
||||
bool Ok = TII->copyRegToReg(FirstMBB, MBBI, GlobalBaseReg, Alpha::R29,
|
||||
&Alpha::GPRCRegClass, &Alpha::GPRCRegClass);
|
||||
assert(Ok && "Couldn't assign to global base register!");
|
||||
RegInfo.addLiveIn(Alpha::R29);
|
||||
|
||||
AlphaFI->setGlobalBaseReg(GlobalBaseReg);
|
||||
return GlobalBaseReg;
|
||||
}
|
||||
|
||||
/// getGlobalRetAddr - Return a virtual register initialized with the
|
||||
/// the global base register value. Output instructions required to
|
||||
/// initialize the register in the function entry block, if necessary.
|
||||
///
|
||||
unsigned AlphaInstrInfo::getGlobalRetAddr(MachineFunction *MF) const {
|
||||
AlphaMachineFunctionInfo *AlphaFI = MF->getInfo<AlphaMachineFunctionInfo>();
|
||||
unsigned GlobalRetAddr = AlphaFI->getGlobalRetAddr();
|
||||
if (GlobalRetAddr != 0)
|
||||
return GlobalRetAddr;
|
||||
|
||||
// Insert the set of GlobalRetAddr into the first MBB of the function
|
||||
MachineBasicBlock &FirstMBB = MF->front();
|
||||
MachineBasicBlock::iterator MBBI = FirstMBB.begin();
|
||||
MachineRegisterInfo &RegInfo = MF->getRegInfo();
|
||||
const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
|
||||
|
||||
GlobalRetAddr = RegInfo.createVirtualRegister(&Alpha::GPRCRegClass);
|
||||
bool Ok = TII->copyRegToReg(FirstMBB, MBBI, GlobalRetAddr, Alpha::R26,
|
||||
&Alpha::GPRCRegClass, &Alpha::GPRCRegClass);
|
||||
assert(Ok && "Couldn't assign to global return address register!");
|
||||
RegInfo.addLiveIn(Alpha::R26);
|
||||
|
||||
AlphaFI->setGlobalRetAddr(GlobalRetAddr);
|
||||
return GlobalRetAddr;
|
||||
}
|
||||
|
@ -90,6 +90,18 @@ public:
|
||||
MachineBasicBlock::iterator MI) const;
|
||||
bool BlockHasNoFallThrough(const MachineBasicBlock &MBB) const;
|
||||
bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const;
|
||||
|
||||
/// getGlobalBaseReg - Return a virtual register initialized with the
|
||||
/// the global base register value. Output instructions required to
|
||||
/// initialize the register in the function entry block, if necessary.
|
||||
///
|
||||
unsigned getGlobalBaseReg(MachineFunction *MF) const;
|
||||
|
||||
/// getGlobalRetAddr - Return a virtual register initialized with the
|
||||
/// the global return address register value. Output instructions required to
|
||||
/// initialize the register in the function entry block, if necessary.
|
||||
///
|
||||
unsigned getGlobalRetAddr(MachineFunction *MF) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
48
lib/Target/Alpha/AlphaMachineFunctionInfo.h
Normal file
48
lib/Target/Alpha/AlphaMachineFunctionInfo.h
Normal file
@ -0,0 +1,48 @@
|
||||
//====- AlphaMachineFuctionInfo.h - Alpha machine function info -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares Alpha-specific per-machine-function information.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef ALPHAMACHINEFUNCTIONINFO_H
|
||||
#define ALPHAMACHINEFUNCTIONINFO_H
|
||||
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// AlphaMachineFunctionInfo - This class is derived from MachineFunction
|
||||
/// private Alpha target-specific information for each MachineFunction.
|
||||
class AlphaMachineFunctionInfo : public MachineFunctionInfo {
|
||||
/// GlobalBaseReg - keeps track of the virtual register initialized for
|
||||
/// use as the global base register. This is used for PIC in some PIC
|
||||
/// relocation models.
|
||||
unsigned GlobalBaseReg;
|
||||
|
||||
/// GlobalRetAddr = keeps track of the virtual register initialized for
|
||||
/// the return address value.
|
||||
unsigned GlobalRetAddr;
|
||||
|
||||
public:
|
||||
AlphaMachineFunctionInfo() : GlobalBaseReg(0), GlobalRetAddr(0) {}
|
||||
|
||||
AlphaMachineFunctionInfo(MachineFunction &MF) : GlobalBaseReg(0),
|
||||
GlobalRetAddr(0) {}
|
||||
|
||||
unsigned getGlobalBaseReg() const { return GlobalBaseReg; }
|
||||
void setGlobalBaseReg(unsigned Reg) { GlobalBaseReg = Reg; }
|
||||
|
||||
unsigned getGlobalRetAddr() const { return GlobalRetAddr; }
|
||||
void setGlobalRetAddr(unsigned Reg) { GlobalRetAddr = Reg; }
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
@ -70,7 +70,19 @@ private:
|
||||
// Include the pieces autogenerated from the target description.
|
||||
#include "MipsGenDAGISel.inc"
|
||||
|
||||
SDValue getGlobalBaseReg();
|
||||
/// getTargetMachine - Return a reference to the TargetMachine, casted
|
||||
/// to the target-specific type.
|
||||
const MipsTargetMachine &getTargetMachine() {
|
||||
return static_cast<const MipsTargetMachine &>(TM);
|
||||
}
|
||||
|
||||
/// getInstrInfo - Return a reference to the TargetInstrInfo, casted
|
||||
/// to the target-specific type.
|
||||
const MipsInstrInfo *getInstrInfo() {
|
||||
return getTargetMachine().getInstrInfo();
|
||||
}
|
||||
|
||||
SDNode *getGlobalBaseReg();
|
||||
SDNode *Select(SDValue N);
|
||||
|
||||
// Complex Pattern.
|
||||
@ -116,19 +128,10 @@ InstructionSelect()
|
||||
|
||||
/// getGlobalBaseReg - Output the instructions required to put the
|
||||
/// GOT address into a register.
|
||||
SDValue MipsDAGToDAGISel::getGlobalBaseReg() {
|
||||
MachineFunction* MF = BB->getParent();
|
||||
unsigned GP = 0;
|
||||
for(MachineRegisterInfo::livein_iterator ii = MF->getRegInfo().livein_begin(),
|
||||
ee = MF->getRegInfo().livein_end(); ii != ee; ++ii)
|
||||
if (ii->first == Mips::GP) {
|
||||
GP = ii->second;
|
||||
break;
|
||||
}
|
||||
assert(GP && "GOT PTR not in liveins");
|
||||
// FIXME is there a sensible place to get debug info for this?
|
||||
return CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
|
||||
DebugLoc::getUnknownLoc(), GP, MVT::i32);
|
||||
SDNode *MipsDAGToDAGISel::getGlobalBaseReg() {
|
||||
MachineFunction *MF = BB->getParent();
|
||||
unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF);
|
||||
return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode();
|
||||
}
|
||||
|
||||
/// ComplexPattern used on MipsInstrInfo
|
||||
@ -321,11 +324,8 @@ Select(SDValue N)
|
||||
}
|
||||
|
||||
// Get target GOT address.
|
||||
case ISD::GLOBAL_OFFSET_TABLE: {
|
||||
SDValue Result = getGlobalBaseReg();
|
||||
ReplaceUses(N, Result);
|
||||
return NULL;
|
||||
}
|
||||
case ISD::GLOBAL_OFFSET_TABLE:
|
||||
return getGlobalBaseReg();
|
||||
|
||||
/// Handle direct and indirect calls when using PIC. On PIC, when
|
||||
/// GOT is smaller than about 64k (small code) the GA target is
|
||||
|
@ -941,9 +941,6 @@ LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG)
|
||||
|
||||
unsigned StackReg = MF.getTarget().getRegisterInfo()->getFrameRegister(MF);
|
||||
|
||||
// GP must be live into PIC and non-PIC call target.
|
||||
AddLiveIn(MF, Mips::GP, Mips::CPURegsRegisterClass);
|
||||
|
||||
// Assign locations to all of the incoming arguments.
|
||||
SmallVector<CCValAssign, 16> ArgLocs;
|
||||
CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs);
|
||||
|
@ -13,8 +13,10 @@
|
||||
|
||||
#include "MipsInstrInfo.h"
|
||||
#include "MipsTargetMachine.h"
|
||||
#include "MipsMachineFunction.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "MipsGenInstrInfo.inc"
|
||||
|
||||
using namespace llvm;
|
||||
@ -621,3 +623,30 @@ ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const
|
||||
Cond[0].setImm(GetOppositeBranchCondition((Mips::CondCode)Cond[0].getImm()));
|
||||
return false;
|
||||
}
|
||||
|
||||
/// getGlobalBaseReg - Return a virtual register initialized with the
|
||||
/// the global base register value. Output instructions required to
|
||||
/// initialize the register in the function entry block, if necessary.
|
||||
///
|
||||
unsigned MipsInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
|
||||
MipsFunctionInfo *MipsFI = MF->getInfo<MipsFunctionInfo>();
|
||||
unsigned GlobalBaseReg = MipsFI->getGlobalBaseReg();
|
||||
if (GlobalBaseReg != 0)
|
||||
return GlobalBaseReg;
|
||||
|
||||
// Insert the set of GlobalBaseReg into the first MBB of the function
|
||||
MachineBasicBlock &FirstMBB = MF->front();
|
||||
MachineBasicBlock::iterator MBBI = FirstMBB.begin();
|
||||
MachineRegisterInfo &RegInfo = MF->getRegInfo();
|
||||
const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
|
||||
|
||||
GlobalBaseReg = RegInfo.createVirtualRegister(Mips::CPURegsRegisterClass);
|
||||
bool Ok = TII->copyRegToReg(FirstMBB, MBBI, GlobalBaseReg, Mips::GP,
|
||||
Mips::CPURegsRegisterClass,
|
||||
Mips::CPURegsRegisterClass);
|
||||
assert(Ok && "Couldn't assign to global base register!");
|
||||
RegInfo.addLiveIn(Mips::GP);
|
||||
|
||||
MipsFI->setGlobalBaseReg(GlobalBaseReg);
|
||||
return GlobalBaseReg;
|
||||
}
|
||||
|
@ -216,6 +216,12 @@ public:
|
||||
/// Insert nop instruction when hazard condition is found
|
||||
virtual void insertNoop(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI) const;
|
||||
|
||||
/// getGlobalBaseReg - Return a virtual register initialized with the
|
||||
/// the global base register value. Output instructions required to
|
||||
/// initialize the register in the function entry block, if necessary.
|
||||
///
|
||||
unsigned getGlobalBaseReg(MachineFunction *MF) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -75,11 +75,16 @@ private:
|
||||
/// holds the virtual register into which the sret argument is passed.
|
||||
unsigned SRetReturnReg;
|
||||
|
||||
/// GlobalBaseReg - keeps track of the virtual register initialized for
|
||||
/// use as the global base register. This is used for PIC in some PIC
|
||||
/// relocation models.
|
||||
unsigned GlobalBaseReg;
|
||||
|
||||
public:
|
||||
MipsFunctionInfo(MachineFunction& MF)
|
||||
: FPStackOffset(0), RAStackOffset(0), CPUTopSavedRegOff(0),
|
||||
FPUTopSavedRegOff(0), GPHolder(-1,-1), HasLoadArgs(false),
|
||||
HasStoreVarArgs(false), SRetReturnReg(0)
|
||||
HasStoreVarArgs(false), SRetReturnReg(0), GlobalBaseReg(0)
|
||||
{}
|
||||
|
||||
int getFPStackOffset() const { return FPStackOffset; }
|
||||
@ -124,6 +129,9 @@ public:
|
||||
|
||||
unsigned getSRetReturnReg() const { return SRetReturnReg; }
|
||||
void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; }
|
||||
|
||||
unsigned getGlobalBaseReg() const { return GlobalBaseReg; }
|
||||
void setGlobalBaseReg(unsigned Reg) { GlobalBaseReg = Reg; }
|
||||
};
|
||||
|
||||
} // end of namespace llvm
|
||||
|
Loading…
x
Reference in New Issue
Block a user