};
/*! Extract the register from the register file */
- INLINE Register getRegister(uint32_t ID) const { return file.get(ID); }
+ INLINE Register getRegister(RegisterIndex ID) const { return file.get(ID); }
/*! Get the register index from the tuple vector */
INLINE RegisterIndex getRegisterIndex(TupleIndex ID, uint32_t which) const {
return file.get(ID, which);
INLINE uint32_t getSrcNum(void) const { return 0; }
INLINE RegisterIndex getSrcIndex(const Function &fn, uint32_t ID) const {
NOT_IMPLEMENTED;
- return 0;
+ return RegisterIndex(0);
}
};
INLINE uint32_t getDstNum(void) const { return 0; }
INLINE RegisterIndex getDstIndex(const Function &fn, uint32_t ID) const {
NOT_IMPLEMENTED;
- return 0;
+ return RegisterIndex(0);
}
};
{
public:
StoreInstruction(Type type,
- RegisterIndex offset,
TupleIndex values,
+ RegisterIndex offset,
MemorySpace memSpace,
uint16_t valueNum)
{
const Function &fn,
std::string &whyNot)
{
- if (UNLIKELY(ID >= fn.regNum())) {
+ if (UNLIKELY(uint16_t(ID) >= fn.regNum())) {
whyNot = "Out-of-bound destination register index";
return false;
}
#define CALL getSrcIndex(fn, ID)
START_FUNCTION(Instruction, RegisterIndex, getSrcIndex(const Function &fn, uint32_t ID))
#include "ir/instruction.hxx"
-END_FUNCTION(Instruction, bool)
+END_FUNCTION(Instruction, RegisterIndex)
#undef CALL
#define CALL wellFormed(fn, whyNot)
}
// CVT
- Instruction CVT(Type dstType, Type srcType, RegisterIndex dst, TupleIndex src) {
+ Instruction CVT(Type dstType, Type srcType, RegisterIndex dst, RegisterIndex src) {
internal::ConvertInstruction insn(dstType, srcType, dst, src);
return insn.convert();
}
/**
* \file register.hpp
- *
* \author Benjamin Segovia <benjamin.segovia@intel.com>
*/
#ifndef __GBE_IR_REGISTER_HPP__
GBE_CLASS(Register);
};
- /*! Register index is the position of the register in the register file */
- typedef uint16_t RegisterIndex;
+ /*! Register index is the position of the register in the register file. We
+ * enforce type safety with this class
+ */
+ class RegisterIndex
+ {
+ public:
+ INLINE RegisterIndex(void) {}
+ explicit INLINE RegisterIndex(uint16_t index) : index(index) {}
+ INLINE operator uint16_t (void) const { return index; }
+ uint16_t value(void) const { return index; }
+ private:
+ uint16_t index;
+ };
- /*! Tuple index is the position of the register index in the tuple vector */
- typedef uint32_t TupleIndex;
+ /*! Tuple index is the position of the register index in the tuple vector. We
+ * enforce type safety with this class
+ */
+ class TupleIndex
+ {
+ public:
+ INLINE TupleIndex(void) {}
+ explicit INLINE TupleIndex(uint16_t index) : index(index) {}
+ INLINE operator uint16_t (void) const { return index; }
+ uint16_t value(void) const { return index; }
+ private:
+ uint16_t index;
+ };
/*! A register file allocates and destroys registers. Basically, we will have
* one register file per function
public:
/*! Return the index of a newly allocated register register */
INLINE RegisterIndex append(Register::Family family) {
- const uint32_t index = regNum();
+ GBE_ASSERT(regNum() <= MAX_INDEX);
+ const uint16_t index = regNum();
const Register reg(family);
- GBE_ASSERT(index <= MAX_INDEX);
regs.push_back(reg);
- return index;
+ return RegisterIndex(index);
}
/*! Make a tuple and return the index to the first element of the tuple */
template <typename First, typename... Rest>
INLINE TupleIndex appendTuple(First first, Rest... rest) {
- const TupleIndex index = regTuples.size();
+ const TupleIndex index = TupleIndex(regTuples.size());
GBE_ASSERT(first < regNum());
regTuples.push_back(first);
appendTuple(rest...);
}
/*! Get the register index from the tuple */
INLINE RegisterIndex get(TupleIndex index, uint32_t which) const {
- GBE_ASSERT(index + which < regTuples.size());
- return regTuples[index + which];
+ GBE_ASSERT(uint16_t(index) + which < regTuples.size());
+ return regTuples[uint16_t(index) + which];
}
/*! Number of registers in the register file */
INLINE uint32_t regNum(void) const { return regs.size(); }
private:
vector<Register> regs; //!< All the registers together
vector<RegisterIndex> regTuples; //!< Tuples are used for many src / dst
+ enum { MAX_INDEX = 0xffff }; //!< register and tuple indices are short
GBE_CLASS(RegisterFile);
};
////////////////////////////////////////////////////////////////////////////////
/// Memory debugger
////////////////////////////////////////////////////////////////////////////////
+#if GBE_DEBUG_MEMORY
namespace gbe
{
-#if GBE_DEBUG_MEMORY
/*! Store each allocation data */
struct AllocData {
INLINE AllocData(void) {}
namespace gbe
{
#if GBE_DEBUG_MEMORY
- void* malloc(size_t size) {
+ void* memAlloc(size_t size) {
void *ptr = std::malloc(size + sizeof(size_t));
*(size_t *) ptr = size;
MemDebuggerInitializeMem((char*) ptr + sizeof(size_t), size);
return (char *) ptr + sizeof(size_t);
}
- void free(void *ptr) {
+ void memFree(void *ptr) {
if (ptr != NULL) {
char *toFree = (char*) ptr - sizeof(size_t);
const size_t size = *(size_t *) toFree;
}
}
#else
- void* malloc(size_t size) { return std::malloc(size); }
- void free(void *ptr) { if (ptr != NULL) std::free(ptr); }
+ void* memAlloc(size_t size) { return std::malloc(size); }
+ void memFree(void *ptr) { if (ptr != NULL) std::free(ptr); }
#endif /* GBE_DEBUG_MEMORY */
} /* namespace gbe */
return ptr;
}
- void alignedFree(void *ptr) { if (ptr) free(ptr); }
+ void alignedFree(void *ptr) { if (ptr) std::free(ptr); }
} /* namespace gbe */
#endif /* __LINUX__ */
namespace gbe
{
/*! regular allocation */
- void* malloc(size_t size);
- void free(void *ptr);
+ void* memAlloc(size_t size);
+ void memFree(void *ptr);
/*! Aligned allocation */
void* alignedMalloc(size_t size, size_t align = 64);
if (AlignOf<TYPE>::value > sizeof(uintptr_t)) \
return gbe::alignedMalloc(size, AlignOf<TYPE>::value); \
else \
- return gbe::malloc(size); \
+ return gbe::memAlloc(size); \
} \
void* operator new[](size_t size) { \
if (AlignOf<TYPE>::value > sizeof(uintptr_t)) \
return gbe::alignedMalloc(size, AlignOf<TYPE>::value); \
else \
- return gbe::malloc(size); \
+ return gbe::memAlloc(size); \
} \
void operator delete(void* ptr) { \
if (AlignOf<TYPE>::value > sizeof(uintptr_t)) \
return gbe::alignedFree(ptr); \
else \
- return gbe::free(ptr); \
+ return gbe::memFree(ptr); \
} \
void operator delete[](void* ptr) { \
if (AlignOf<TYPE>::value > sizeof(uintptr_t)) \
return gbe::alignedFree(ptr); \
else \
- return gbe::free(ptr); \
+ return gbe::memFree(ptr); \
} \
/*! Declare a class with custom allocators */
do { gbe::MemDebuggerRemoveAlloc(X); delete[] X; } while (0)
#define GBE_MALLOC(SZ) \
- gbe::MemDebuggerInsertAlloc(gbe::malloc(SZ),__FILE__, __FUNCTION__, __LINE__)
+ gbe::MemDebuggerInsertAlloc(gbe::memAlloc(SZ),__FILE__, __FUNCTION__, __LINE__)
#define GBE_FREE(X) \
- do { gbe::MemDebuggerRemoveAlloc(X); gbe::free(X); } while (0)
+ do { gbe::MemDebuggerRemoveAlloc(X); gbe::memFree(X); } while (0)
#define GBE_ALIGNED_FREE(X) \
do { gbe::MemDebuggerRemoveAlloc(X); gbe::alignedFree(X); } while (0)