//===- PTXMachineFuctionInfo.h - PTX 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 PTX-specific per-machine-function information.
//
//===----------------------------------------------------------------------===//
#ifndef PTX_MACHINE_FUNCTION_INFO_H
#define PTX_MACHINE_FUNCTION_INFO_H
#include "PTX.h"
#include "PTXParamManager.h"
#include "PTXRegisterInfo.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {
/// PTXMachineFunctionInfo - This class is derived from MachineFunction and
/// contains private PTX target-specific information for each MachineFunction.
///
class PTXMachineFunctionInfo : public MachineFunctionInfo {
private:
bool IsKernel;
DenseSet<unsigned> RegArgs;
DenseSet<unsigned> RegRets;
typedef std::vector<unsigned> RegisterList;
typedef DenseMap<const TargetRegisterClass*, RegisterList> RegisterMap;
typedef DenseMap<unsigned, std::string> RegisterNameMap;
typedef DenseMap<int, std::string> FrameMap;
RegisterMap UsedRegs;
RegisterNameMap RegNames;
FrameMap FrameSymbols;
PTXParamManager ParamManager;
public:
typedef DenseSet<unsigned>::const_iterator reg_iterator;
PTXMachineFunctionInfo(MachineFunction &MF)
: IsKernel(false) {
UsedRegs[PTX::RegPredRegisterClass] = RegisterList();
UsedRegs[PTX::RegI16RegisterClass] = RegisterList();
UsedRegs[PTX::RegI32RegisterClass] = RegisterList();
UsedRegs[PTX::RegI64RegisterClass] = RegisterList();
UsedRegs[PTX::RegF32RegisterClass] = RegisterList();
UsedRegs[PTX::RegF64RegisterClass] = RegisterList();
}
/// getParamManager - Returns the PTXParamManager instance for this function.
PTXParamManager& getParamManager() { return ParamManager; }
const PTXParamManager& getParamManager() const { return ParamManager; }
/// setKernel/isKernel - Gets/sets a flag that indicates if this function is
/// a PTX kernel function.
void setKernel(bool _IsKernel=true) { IsKernel = _IsKernel; }
bool isKernel() const { return IsKernel; }
/// argreg_begin/argreg_end - Returns iterators to the set of registers
/// containing function arguments.
reg_iterator argreg_begin() const { return RegArgs.begin(); }
reg_iterator argreg_end() const { return RegArgs.end(); }
/// retreg_begin/retreg_end - Returns iterators to the set of registers
/// containing the function return values.
reg_iterator retreg_begin() const { return RegRets.begin(); }
reg_iterator retreg_end() const { return RegRets.end(); }
/// addRetReg - Adds a register to the set of return-value registers.
void addRetReg(unsigned Reg) {
if (!RegRets.count(Reg)) {
RegRets.insert(Reg);
std::string name;
name = "%ret";
name += utostr(RegRets.size() - 1);
RegNames[Reg] = name;
}
}
/// addArgReg - Adds a register to the set of function argument registers.
void addArgReg(unsigned Reg) {
RegArgs.insert(Reg);
std::string name;
name = "%param";
name += utostr(RegArgs.size() - 1);
RegNames[Reg] = name;
}
/// addVirtualRegister - Adds a virtual register to the set of all used
/// registers in the function.
void addVirtualRegister(const TargetRegisterClass *TRC, unsigned Reg) {
std::string name;
// Do not count registers that are argument/return registers.
if (!RegRets.count(Reg) && !RegArgs.count(Reg)) {
UsedRegs[TRC].push_back(Reg);
if (TRC == PTX::RegPredRegisterClass)
name = "%p";
else if (TRC == PTX::RegI16RegisterClass)
name = "%rh";
else if (TRC == PTX::RegI32RegisterClass)
name = "%r";
else if (TRC == PTX::RegI64RegisterClass)
name = "%rd";
else if (TRC == PTX::RegF32RegisterClass)
name = "%f";
else if (TRC == PTX::RegF64RegisterClass)
name = "%fd";
else
llvm_unreachable("Invalid register class");
name += utostr(UsedRegs[TRC].size() - 1);
RegNames[Reg] = name;
}
}
/// getRegisterName - Returns the name of the specified virtual register. This
/// name is used during PTX emission.
const char *getRegisterName(unsigned Reg) const {
if (RegNames.count(Reg))
return RegNames.find(Reg)->second.c_str();
else if (Reg == PTX::NoRegister)
return "%noreg";
else
llvm_unreachable("Register not in register name map");
}
/// getNumRegistersForClass - Returns the number of virtual registers that are
/// used for the specified register class.
unsigned getNumRegistersForClass(const TargetRegisterClass *TRC) const {
return UsedRegs.lookup(TRC).size();
}
/// getFrameSymbol - Returns the symbol name for the given FrameIndex.
const char* getFrameSymbol(int FrameIndex) {
if (FrameSymbols.count(FrameIndex)) {
return FrameSymbols.lookup(FrameIndex).c_str();
} else {
std::string Name = "__local";
Name += utostr(FrameIndex);
// The whole point of caching this name is to ensure the pointer we pass
// to any getExternalSymbol() calls will remain valid for the lifetime of
// the back-end instance. This is to work around an issue in SelectionDAG
// where symbol names are expected to be life-long strings.
FrameSymbols[FrameIndex] = Name;
return FrameSymbols[FrameIndex].c_str();
}
}
}; // class PTXMachineFunctionInfo
} // namespace llvm
#endif // PTX_MACHINE_FUNCTION_INFO_H