PTXMachineFunctionInfo.h [plain text]
#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 {
class PTXMachineFunctionInfo : public MachineFunctionInfo {
virtual void anchor();
bool IsKernel;
DenseSet<unsigned> RegArgs;
DenseSet<unsigned> RegRets;
typedef DenseMap<int, std::string> FrameMap;
FrameMap FrameSymbols;
struct RegisterInfo {
unsigned Reg;
unsigned Type;
unsigned Space;
unsigned Offset;
unsigned Encoded;
};
typedef DenseMap<unsigned, RegisterInfo> RegisterInfoMap;
RegisterInfoMap RegInfo;
PTXParamManager ParamManager;
public:
typedef DenseSet<unsigned>::const_iterator reg_iterator;
PTXMachineFunctionInfo(MachineFunction &MF)
: IsKernel(false) {
}
PTXParamManager& getParamManager() { return ParamManager; }
const PTXParamManager& getParamManager() const { return ParamManager; }
void setKernel(bool _IsKernel=true) { IsKernel = _IsKernel; }
bool isKernel() const { return IsKernel; }
reg_iterator argreg_begin() const { return RegArgs.begin(); }
reg_iterator argreg_end() const { return RegArgs.end(); }
reg_iterator retreg_begin() const { return RegRets.begin(); }
reg_iterator retreg_end() const { return RegRets.end(); }
void addRegister(unsigned Reg, unsigned RegType, unsigned RegSpace) {
if (!RegInfo.count(Reg)) {
RegisterInfo Info;
Info.Reg = Reg;
Info.Type = RegType;
Info.Space = RegSpace;
Info.Offset = 0;
for(RegisterInfoMap::const_iterator i = RegInfo.begin(),
e = RegInfo.end(); i != e; ++i) {
const RegisterInfo& RI = i->second;
if (RI.Space == RegSpace)
if (RI.Space != PTXRegisterSpace::Reg || RI.Type == Info.Type)
Info.Offset++;
}
Info.Encoded = (Info.Offset << 6) | (Info.Type << 3) | Info.Space;
RegInfo[Reg] = Info;
if (RegSpace == PTXRegisterSpace::Argument)
RegArgs.insert(Reg);
else if (RegSpace == PTXRegisterSpace::Return)
RegRets.insert(Reg);
}
}
unsigned countRegisters(unsigned RegType, unsigned RegSpace) const {
unsigned Count = 0;
for(RegisterInfoMap::const_iterator i = RegInfo.begin(), e = RegInfo.end();
i != e; ++i) {
const RegisterInfo& RI = i->second;
if (RI.Type == RegType && RI.Space == RegSpace)
Count++;
}
return Count;
}
unsigned getEncodedRegister(unsigned Reg) const {
return RegInfo.lookup(Reg).Encoded;
}
void addRetReg(unsigned Reg) {
if (!RegRets.count(Reg)) {
RegRets.insert(Reg);
}
}
void addArgReg(unsigned Reg) {
RegArgs.insert(Reg);
}
std::string getRegisterName(unsigned Reg) const {
if (RegInfo.count(Reg)) {
const RegisterInfo& RI = RegInfo.lookup(Reg);
std::string Name;
raw_string_ostream NameStr(Name);
decodeRegisterName(NameStr, RI.Encoded);
NameStr.flush();
return Name;
}
else if (Reg == PTX::NoRegister)
return "%noreg";
else
llvm_unreachable("Register not in register name map");
}
std::string getEncodedRegisterName(unsigned EncodedReg) const {
std::string Name;
raw_string_ostream NameStr(Name);
decodeRegisterName(NameStr, EncodedReg);
NameStr.flush();
return Name;
}
unsigned getRegisterType(unsigned Reg) const {
if (RegInfo.count(Reg))
return RegInfo.lookup(Reg).Type;
else
llvm_unreachable("Unknown register");
}
unsigned getOffsetForRegister(unsigned Reg) const {
if (RegInfo.count(Reg))
return RegInfo.lookup(Reg).Offset;
else
return 0;
}
const char* getFrameSymbol(int FrameIndex) {
if (FrameSymbols.count(FrameIndex)) {
return FrameSymbols.lookup(FrameIndex).c_str();
} else {
std::string Name = "__local";
Name += utostr(FrameIndex);
FrameSymbols[FrameIndex] = Name;
return FrameSymbols[FrameIndex].c_str();
}
}
}; }
#endif // PTX_MACHINE_FUNCTION_INFO_H