From 9911405183f8596fe9d521467f83f6652a296cf4 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 3 Jun 2009 20:30:14 +0000 Subject: [PATCH] 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 --- lib/Target/Alpha/AlphaISelDAGToDAG.cpp | 68 +++++++++------------ lib/Target/Alpha/AlphaISelLowering.cpp | 3 - lib/Target/Alpha/AlphaInstrInfo.cpp | 53 ++++++++++++++++ lib/Target/Alpha/AlphaInstrInfo.h | 12 ++++ lib/Target/Alpha/AlphaMachineFunctionInfo.h | 48 +++++++++++++++ lib/Target/Mips/MipsISelDAGToDAG.cpp | 38 ++++++------ lib/Target/Mips/MipsISelLowering.cpp | 3 - lib/Target/Mips/MipsInstrInfo.cpp | 29 +++++++++ lib/Target/Mips/MipsInstrInfo.h | 6 ++ lib/Target/Mips/MipsMachineFunction.h | 10 ++- 10 files changed, 205 insertions(+), 65 deletions(-) create mode 100644 lib/Target/Alpha/AlphaMachineFunctionInfo.h diff --git a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp index affcd3e7fec..e3f631a1f5b 100644 --- a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp +++ b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp @@ -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(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, diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp index 10011125cf8..7ed8ef60302 100644 --- a/lib/Target/Alpha/AlphaISelLowering.cpp +++ b/lib/Target/Alpha/AlphaISelLowering.cpp @@ -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[] = { diff --git a/lib/Target/Alpha/AlphaInstrInfo.cpp b/lib/Target/Alpha/AlphaInstrInfo.cpp index a54d97d33c4..229f9d4784a 100644 --- a/lib/Target/Alpha/AlphaInstrInfo.cpp +++ b/lib/Target/Alpha/AlphaInstrInfo.cpp @@ -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 &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(); + 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(); + 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; +} diff --git a/lib/Target/Alpha/AlphaInstrInfo.h b/lib/Target/Alpha/AlphaInstrInfo.h index 182aa32f447..ea0988553ac 100644 --- a/lib/Target/Alpha/AlphaInstrInfo.h +++ b/lib/Target/Alpha/AlphaInstrInfo.h @@ -90,6 +90,18 @@ public: MachineBasicBlock::iterator MI) const; bool BlockHasNoFallThrough(const MachineBasicBlock &MBB) const; bool ReverseBranchCondition(SmallVectorImpl &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; }; } diff --git a/lib/Target/Alpha/AlphaMachineFunctionInfo.h b/lib/Target/Alpha/AlphaMachineFunctionInfo.h new file mode 100644 index 00000000000..47de5dfad94 --- /dev/null +++ b/lib/Target/Alpha/AlphaMachineFunctionInfo.h @@ -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 diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp index f05ac702ccd..53de1bbea66 100644 --- a/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -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(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 diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 9281940019a..4517cfc96a4 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -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 ArgLocs; CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); diff --git a/lib/Target/Mips/MipsInstrInfo.cpp b/lib/Target/Mips/MipsInstrInfo.cpp index 6225fa9c988..92af973b0d2 100644 --- a/lib/Target/Mips/MipsInstrInfo.cpp +++ b/lib/Target/Mips/MipsInstrInfo.cpp @@ -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 &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(); + 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; +} diff --git a/lib/Target/Mips/MipsInstrInfo.h b/lib/Target/Mips/MipsInstrInfo.h index 334244e6601..6655c6749fd 100644 --- a/lib/Target/Mips/MipsInstrInfo.h +++ b/lib/Target/Mips/MipsInstrInfo.h @@ -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; }; } diff --git a/lib/Target/Mips/MipsMachineFunction.h b/lib/Target/Mips/MipsMachineFunction.h index b95394ec81c..ac3cdfd38e1 100644 --- a/lib/Target/Mips/MipsMachineFunction.h +++ b/lib/Target/Mips/MipsMachineFunction.h @@ -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