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:
Dan Gohman 2009-06-03 20:30:14 +00:00
parent c553462c29
commit 9911405183
10 changed files with 205 additions and 65 deletions

View File

@ -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,

View File

@ -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[] = {

View File

@ -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;
}

View File

@ -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;
};
}

View 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

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
};
}

View File

@ -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