#include "backend/gen_program.hpp"
#include "backend/gen_defs.hpp"
#include "backend/gen_eu.hpp"
+#include "ir/function.hpp"
#include <cstring>
namespace gbe
Context(unit, name) {}
GenContext::~GenContext(void) {}
+ void GenContext::allocateRegister(void) {
+ GBE_ASSERT(fn.getProfile() == ir::PROFILE_OCL);
+
+ // First we build the set of all used registers
+ set<ir::Register> usedRegs;
+ fn.foreachInstruction([&usedRegs](const ir::Instruction &insn) {
+ const uint32_t srcNum = insn.getSrcNum(), dstNum = insn.getDstNum();
+ for (uint32_t srcID = 0; srcID < srcNum; ++srcID)
+ usedRegs.insert(insn.getSrc(srcID));
+ for (uint32_t dstID = 0; dstID < dstNum; ++dstID)
+ usedRegs.insert(insn.getDst(dstID));
+ });
+
+
+ }
+
void GenContext::emitCode(void) {
GenKernel *genKernel = static_cast<GenKernel*>(this->kernel);
GenEmitter *p = (GenEmitter*) GBE_MALLOC(sizeof(GenEmitter));
std::memcpy(genKernel->insns, p->store, genKernel->insnNum * sizeof(GenInstruction));
GBE_FREE(p);
}
+
Kernel *GenContext::allocateKernel(void) {
return GBE_NEW(GenKernel, name);
}
* defined (i.e. not out-of-bound)
*/
static INLINE bool checkRegisterData(RegisterFamily family,
- const Register ID,
+ const Register &ID,
const Function &fn,
std::string &whyNot)
{
return true;
}
+ /*! Special registers are *not* writeable */
+ static INLINE bool checkSpecialRegForWrite(const Register ®,
+ const Function &fn,
+ std::string &whyNot)
+ {
+ if (fn.isSpecialReg(reg) == true) {
+ whyNot = "Special registers are not writeable";
+ return false;
+ }
+ return true;
+ }
+
// Unary and binary instructions share the same rules
template <uint32_t srcNum>
INLINE bool NaryInstruction<srcNum>::wellFormed(const Function &fn, std::string &whyNot) const
{
const RegisterFamily family = getFamily(this->type);
+ if (UNLIKELY(checkSpecialRegForWrite(dst, fn, whyNot) == false))
+ return false;
if (UNLIKELY(checkRegisterData(family, dst, fn, whyNot) == false))
return false;
for (uint32_t srcID = 0; srcID < srcNum; ++srcID)
INLINE bool TernaryInstruction::wellFormed(const Function &fn, std::string &whyNot) const
{
const RegisterFamily family = getFamily(this->type);
+ if (UNLIKELY(checkSpecialRegForWrite(dst, fn, whyNot) == false))
+ return false;
if (UNLIKELY(checkRegisterData(family, dst, fn, whyNot) == false))
return false;
if (UNLIKELY(src + 3u > fn.tupleNum())) {
INLINE bool SelectInstruction::wellFormed(const Function &fn, std::string &whyNot) const
{
const RegisterFamily family = getFamily(this->type);
+ if (UNLIKELY(checkSpecialRegForWrite(dst, fn, whyNot) == false))
+ return false;
if (UNLIKELY(checkRegisterData(family, dst, fn, whyNot) == false))
return false;
if (UNLIKELY(src + 3u > fn.tupleNum())) {
// boolean
INLINE bool CompareInstruction::wellFormed(const Function &fn, std::string &whyNot) const
{
+ if (UNLIKELY(checkSpecialRegForWrite(dst, fn, whyNot) == false))
+ return false;
if (UNLIKELY(checkRegisterData(FAMILY_BOOL, dst, fn, whyNot) == false))
return false;
const RegisterFamily family = getFamily(this->type);
{
const RegisterFamily dstFamily = getFamily(dstType);
const RegisterFamily srcFamily = getFamily(srcType);
+ if (UNLIKELY(checkSpecialRegForWrite(dst, fn, whyNot) == false))
+ return false;
if (UNLIKELY(checkRegisterData(dstFamily, dst, fn, whyNot) == false))
return false;
if (UNLIKELY(checkRegisterData(srcFamily, src, fn, whyNot) == false))
INLINE bool LoadInstruction::wellFormed(const Function &fn, std::string &whyNot) const
{
+ const uint32_t dstNum = this->getDstNum();
+ for (uint32_t dstID = 0; dstID < dstNum; ++dstID) {
+ const Register reg = this->getDst(fn, dstID);
+ const bool isOK = checkSpecialRegForWrite(reg, fn, whyNot);
+ if (UNLIKELY(isOK == false)) return false;
+ }
return wellFormedLoadStore(*this, fn, whyNot);
}
return false;
}
const RegisterFamily family = getFamily(type);
+ if (UNLIKELY(checkSpecialRegForWrite(dst, fn, whyNot) == false))
+ return false;
if (UNLIKELY(checkRegisterData(family, dst, fn, whyNot) == false))
return false;
return true;
END_FUNCTION(Instruction, uint32_t)
#undef CALL
-#define CALL wellFormed(fn, whyNot)
-START_FUNCTION(Instruction, bool, wellFormed(const Function &fn, std::string &whyNot))
-#include "ir/instruction.hxx"
-END_FUNCTION(Instruction, bool)
-#undef CALL
-
#undef DECL_INSN
#define DECL_INSN(OPCODE, CLASS) \
return reinterpret_cast<const internal::CLASS*>(this)->CALL; \
}
+#define CALL wellFormed(fn, whyNot)
+START_FUNCTION(Instruction, bool, wellFormed(std::string &whyNot))
+#include "ir/instruction.hxx"
+END_FUNCTION(Instruction, bool)
+#undef CALL
+
#define CALL getDst(fn, ID)
START_FUNCTION(Instruction, Register, getDst(uint32_t ID))
#include "ir/instruction.hxx"