Made the instructions double-chain list elements Renamed the register family s/Regist...
authorBenjamin Segovia <segovia.benjamin@gmail.com>
Tue, 13 Mar 2012 01:36:14 +0000 (18:36 -0700)
committerKeith Packard <keithp@keithp.com>
Fri, 10 Aug 2012 23:15:36 +0000 (16:15 -0700)
15 files changed:
backend/src/ir/context.cpp
backend/src/ir/context.hpp
backend/src/ir/function.cpp
backend/src/ir/function.hpp
backend/src/ir/instruction.cpp
backend/src/ir/instruction.hpp
backend/src/ir/opt_local_remove_foo_mov.cpp [new file with mode: 0644]
backend/src/ir/profile.cpp
backend/src/ir/register.cpp
backend/src/ir/register.hpp
backend/src/ir/type.hpp
backend/src/llvm/llvm_gen_backend.cpp
backend/src/sys/alloc.hpp
backend/src/utest/utest_context.cpp
backend/src/utest/utest_llvm.cpp

index 6be17d6..460b802 100644 (file)
@@ -65,7 +65,7 @@ namespace ir {
     return *fn;
   }
 
-  Register Context::reg(RegisterData::Family family) {
+  Register Context::reg(RegisterFamily family) {
     GBE_ASSERTM(fn != NULL, "No function currently defined");
     return fn->newRegister(family);
   }
@@ -129,6 +129,7 @@ namespace ir {
 
     // Append the instruction in the stream
     Instruction *insnPtr = fn->newInstruction();
+
     *insnPtr = insn;
 #if GBE_DEBUG
     std::string whyNot;
index 9ffc5f6..cc8545c 100644 (file)
@@ -53,7 +53,7 @@ namespace ir {
     /*! Close the function */
     void endFunction(void);
     /*! Create a new register with the given family for the current function */
-    Register reg(RegisterData::Family family);
+    Register reg(RegisterFamily family);
     /*! Create a new immediate value */
     template <typename T> INLINE ImmediateIndex newImmediate(T value) {
       const Immediate imm(value);
@@ -64,7 +64,7 @@ namespace ir {
       GBE_ASSERTM(fn != NULL, "No function currently defined");
       const Immediate imm(value);
       const ImmediateIndex index = fn->newImmediate(imm);
-      const RegisterData::Family family = getFamily(imm.type);
+      const RegisterFamily family = getFamily(imm.type);
       const Register reg = this->reg(family);
       this->LOADI(imm.type, reg, index);
       return reg;
index f8a7282..06c2697 100644 (file)
@@ -83,7 +83,7 @@ namespace ir {
     for (uint32_t i = 0; i < fn.blockNum(); ++i) {
       const BasicBlock &bb = fn.getBlock(i);
       bb.apply([&out, &fn] (const Instruction &insn) {
-        out << insn.proxy(fn) << std::endl;
+        out << insn << std::endl;
       });
       out << std::endl;
     }
@@ -91,10 +91,13 @@ namespace ir {
     return out;
   }
 
-  BasicBlock::BasicBlock(Function &fn) : fn(fn) {}
+  BasicBlock::BasicBlock(Function &fn) : fn(fn) {
+    this->first = this->last = NULL;
+  }
   BasicBlock::~BasicBlock(void) {
-    for (auto it = instructions.begin(); it != instructions.end(); ++it)
-      fn.deleteInstruction(*it);
+    this->apply([this] (Instruction &insn) {
+     this->fn.deleteInstruction(&insn);
+    });
   }
 
 } /* namespace ir */
index 8ef0c0d..ae1fc43 100644 (file)
@@ -50,19 +50,31 @@ namespace ir {
     /*! Releases all the instructions */
     ~BasicBlock(void);
     /*! Append a new instruction in the stream */
-    void append(Instruction &insn) { instructions.push_back(&insn); }
-    /*! Return the number of instruction in the block */
-    INLINE uint32_t insnNum(void) { return instructions.size(); }
+    void append(Instruction &insn) {
+      if (last != NULL) last->setSuccessor(&insn);
+      if (first == NULL) first = &insn;
+      insn.setParent(this);
+      insn.setSuccessor(NULL);
+      insn.setPredecessor(last);
+      last = &insn;
+    }
     /*! Apply the given functor on all instructions */
     template <typename T>
     INLINE void apply(const T &functor) const {
-      for (auto it = instructions.begin(); it != instructions.end(); ++it)
-        functor(**it);
+      Instruction *curr = first;
+      while (curr) {
+        functor(*curr);
+        curr = curr->getSuccessor();
+      }
     }
+    /*! Get the parent function */
+    Function &getParent(void) { return fn; }
+    const Function &getParent(void) const { return fn; }
   private:
-    friend class Function;           //!< Owns the basic blocks
-    list<Instruction*> instructions; //!< Sequence of instructions in the block
-    Function &fn;                    //!< Function the block belongs to
+    friend class Function; //!< Owns the basic blocks
+    Instruction *first;    //!< First instruction in the block
+    Instruction *last;     //!< Last instruction in the block
+    Function &fn;          //!< Function the block belongs to
     GBE_CLASS(BasicBlock);
   };
 
@@ -79,7 +91,7 @@ namespace ir {
     /*! Get the function profile */
     INLINE Profile getProfile(void) const { return profile; }
     /*! Get a new valid register */
-    INLINE Register newRegister(RegisterData::Family family) {
+    INLINE Register newRegister(RegisterFamily family) {
       return this->file.append(family);
     }
     /*! Get the function name */
@@ -87,7 +99,7 @@ namespace ir {
     /*! Extract the register from the register file */
     INLINE RegisterData getRegisterData(Register ID) const { return file.get(ID); }
     /*! Get the register family from the register itself */
-    INLINE RegisterData::Family getRegisterFamiy(Register ID) const {
+    INLINE RegisterFamily getRegisterFamiy(Register ID) const {
       return this->getRegisterData(ID).family;
     }
     /*! Get the register index from the tuple vector */
index 9c60220..a9adb5f 100644 (file)
@@ -461,7 +461,7 @@ namespace ir {
     /*! All Nary instruction register must be of the same family and properly
      *  defined (i.e. not out-of-bound)
      */
-    static INLINE bool checkRegisterData(RegisterData::Family family,
+    static INLINE bool checkRegisterData(RegisterFamily family,
                                          const Register ID,
                                          const Function &fn,
                                          std::string &whyNot)
@@ -482,7 +482,7 @@ namespace ir {
     template <uint32_t srcNum>
     INLINE bool NaryInstruction<srcNum>::wellFormed(const Function &fn, std::string &whyNot) const
     {
-      const RegisterData::Family family = getFamily(this->type);
+      const RegisterFamily family = getFamily(this->type);
       if (UNLIKELY(checkRegisterData(family, dst, fn, whyNot) == false))
         return false;
       for (uint32_t srcID = 0; srcID < srcNum; ++srcID)
@@ -494,7 +494,7 @@ namespace ir {
     // Idem for ternary instructions except that sources are in a tuple
     INLINE bool TernaryInstruction::wellFormed(const Function &fn, std::string &whyNot) const
     {
-      const RegisterData::Family family = getFamily(this->type);
+      const RegisterFamily family = getFamily(this->type);
       if (UNLIKELY(checkRegisterData(family, dst, fn, whyNot) == false))
         return false;
       if (UNLIKELY(src + 3u > fn.tupleNum())) {
@@ -512,7 +512,7 @@ namespace ir {
     // First source must a boolean. Other must match the destination type
     INLINE bool SelectInstruction::wellFormed(const Function &fn, std::string &whyNot) const
     {
-      const RegisterData::Family family = getFamily(this->type);
+      const RegisterFamily family = getFamily(this->type);
       if (UNLIKELY(checkRegisterData(family, dst, fn, whyNot) == false))
         return false;
       if (UNLIKELY(src + 3u > fn.tupleNum())) {
@@ -520,7 +520,7 @@ namespace ir {
         return false;
       }
       const Register regID = fn.getRegister(src, 0);
-      if (UNLIKELY(checkRegisterData(RegisterData::BOOL, regID, fn, whyNot) == false))
+      if (UNLIKELY(checkRegisterData(FAMILY_BOOL, regID, fn, whyNot) == false))
         return false;
       for (uint32_t srcID = 1; srcID < 3; ++srcID) {
         const Register regID = fn.getRegister(src, srcID);
@@ -534,9 +534,9 @@ namespace ir {
     // boolean
     INLINE bool CompareInstruction::wellFormed(const Function &fn, std::string &whyNot) const
     {
-      if (UNLIKELY(checkRegisterData(RegisterData::BOOL, dst, fn, whyNot) == false))
+      if (UNLIKELY(checkRegisterData(FAMILY_BOOL, dst, fn, whyNot) == false))
         return false;
-      const RegisterData::Family family = getFamily(this->type);
+      const RegisterFamily family = getFamily(this->type);
       for (uint32_t srcID = 0; srcID < 2; ++srcID)
         if (UNLIKELY(checkRegisterData(family, src[srcID], fn, whyNot) == false))
           return false;
@@ -546,8 +546,8 @@ namespace ir {
     // We can convert anything to anything, but types and families must match
     INLINE bool ConvertInstruction::wellFormed(const Function &fn, std::string &whyNot) const
     {
-      const RegisterData::Family dstFamily = getFamily(dstType);
-      const RegisterData::Family srcFamily = getFamily(srcType);
+      const RegisterFamily dstFamily = getFamily(dstType);
+      const RegisterFamily srcFamily = getFamily(srcType);
       if (UNLIKELY(checkRegisterData(dstFamily, dst, fn, whyNot) == false))
         return false;
       if (UNLIKELY(checkRegisterData(srcFamily, src, fn, whyNot) == false))
@@ -568,7 +568,7 @@ namespace ir {
         return false;
       }
       // Check all registers
-      const RegisterData::Family family = getFamily(insn.type);
+      const RegisterFamily family = getFamily(insn.type);
       for (uint32_t valueID = 0; valueID < insn.valueNum; ++valueID) {
         const Register regID = fn.getRegister(insn.values, valueID);
         if (UNLIKELY(checkRegisterData(family, regID, fn, whyNot) == false))
@@ -604,7 +604,7 @@ namespace ir {
         whyNot = "Inconsistant type for the immediate value to load";
         return false;
       }
-      const RegisterData::Family family = getFamily(type);
+      const RegisterFamily family = getFamily(type);
       if (UNLIKELY(checkRegisterData(family, dst, fn, whyNot) == false))
         return false;
       return true;
@@ -635,7 +635,7 @@ namespace ir {
           return false;
         }
       if (hasPredicate)
-        if (UNLIKELY(checkRegisterData(RegisterData::BOOL, predicate, fn, whyNot) == false))
+        if (UNLIKELY(checkRegisterData(FAMILY_BOOL, predicate, fn, whyNot) == false))
           return false;
       return true;
     }
@@ -750,7 +750,7 @@ namespace ir {
   return HelperIntrospection<CLASS, RefClass>::value == 1;
 
 #define START_INTROSPECTION(CLASS)                                \
-  static_assert(sizeof(internal::CLASS) == sizeof(Instruction),   \
+  static_assert(sizeof(internal::CLASS) == sizeof(uint64_t),      \
                 "Bad instruction size");                          \
   static_assert(offsetof(internal::CLASS, opcode) == 0,           \
                 "Bad opcode offset");                             \
@@ -1024,10 +1024,11 @@ DECL_MEM_FN(BranchInstruction, LabelIndex, getLabelIndex(void), getLabelIndex())
     return insn.convert();
   }
 
-  std::ostream &operator<< (std::ostream &out, const Instruction::Proxy &proxy)
+  std::ostream &operator<< (std::ostream &out, const Instruction &insn)
   {
-    const Instruction &insn = proxy.insn;
-    const Function &fn = proxy.fn;
+    GBE_ASSERT(insn.getParent() != NULL);
+    const BasicBlock *bb = insn.getParent();
+    const Function &fn = bb->getParent();
     switch (insn.getOpcode()) {
 #define DECL_INSN(OPCODE, CLASS)                                     \
       case OP_##OPCODE:                                              \
index eb0126f..4f00dd4 100644 (file)
@@ -60,6 +60,9 @@ namespace ir {
    */
   class Function;
 
+  /*! Contains the stream of instructions */
+  class BasicBlock;
+
   ///////////////////////////////////////////////////////////////////////////
   /// All public instruction classes as manipulated by all public classes
   ///////////////////////////////////////////////////////////////////////////
@@ -73,6 +76,8 @@ namespace ir {
       opcode = Opcode(stream[0]);
       for (uint32_t byte = 0; byte < opaqueSize; ++byte)
         opaque[byte] = stream[byte+1];
+      predecessor = successor = NULL;
+      parent = NULL;
     }
     /*! Uninitialize instruction */
     INLINE Instruction(void) {}
@@ -90,6 +95,18 @@ namespace ir {
     RegisterData getDst(const Function &fn, uint32_t ID = 0u) const;
     /*! Get the register of the given destination */
     RegisterData getSrc(const Function &fn, uint32_t ID = 0u) const;
+    /*! Get / set the previous instruction in the stream */
+    Instruction *getPredecessor(void) { return predecessor; }
+    const Instruction *getPredecessor(void) const { return predecessor; }
+    void setPredecessor(Instruction *insn) { this->predecessor = insn; }
+    /*! Get / set the next instruction in the stream */
+    Instruction *getSuccessor(void) { return successor; }
+    const Instruction *getSuccessor(void) const { return successor; }
+    void setSuccessor(Instruction *insn) { this->successor = insn; }
+    /*! Get / set the parent basic block */
+    BasicBlock *getParent(void) { return parent; }
+    const BasicBlock *getParent(void) const { return parent; }
+    void setParent(BasicBlock *block) { this->parent = block; }
     /*! Check that the instruction is well formed (type properly match,
      *  registers not of bound and so on). If not well formed, provide a reason
      *  in string why
@@ -101,30 +118,18 @@ namespace ir {
     template <typename T> INLINE bool isMemberOf(void) const {
       return T::isClassOf(*this);
     }
-    /*! Since we need the function to get all the instruction information, we
-     *  build a small temporary structure to forward both the instruction and
-     *  the function
-     */
-    struct Proxy {
-      INLINE Proxy(const Function &fn, const Instruction &insn) :
-        fn(fn), insn(insn) {}
-      const Function &fn;
-      const Instruction &insn;
-    };
-    /*! Build a proxy from the instruction */
-    INLINE Proxy proxy(const Function &fn) const { return Proxy(fn, *this); }
 
   protected:
     enum { opaqueSize = sizeof(uint64_t)-sizeof(uint8_t) };
     Opcode opcode;           //!< Idendifies the instruction
     char opaque[opaqueSize]; //!< Remainder of it
+    Instruction *predecessor;//!< Previous instruction in the basic block
+    Instruction *successor;  //!< Next instruction in the basic block
+    BasicBlock *parent;      //!< The basic block containing the instruction
   };
 
   /*! Output the instruction string in the given stream */
-  std::ostream &operator<< (std::ostream &out, const Instruction::Proxy &proxy);
-
-  // Check that the instruction is properly formed by the compiler
-  static_assert(sizeof(Instruction)==sizeof(uint64_t), "Bad instruction size");
+  std::ostream &operator<< (std::ostream &out, const Instruction &proxy);
 
   /*! Unary instructions are typed. dst and sources share the same type */
   class UnaryInstruction : public Instruction {
@@ -292,22 +297,26 @@ namespace ir {
    */
   template <typename T>
   INLINE T *cast(Instruction *insn) {
-    GBE_ASSERTM(insn->isMemberOf<T>() == true, "Invalid instruction cast");
-    return reinterpret_cast<T*>(insn);
+    if(insn->isMemberOf<T>())
+      return reinterpret_cast<T*>(insn);
+    else
+      return NULL;
   }
   template <typename T>
   INLINE const T *cast(const Instruction *insn) {
-    GBE_ASSERTM(insn->isMemberOf<T>() == true, "Invalid instruction cast");
-    return reinterpret_cast<const T*>(insn);
+    if(insn->isMemberOf<T>())
+      return reinterpret_cast<const T*>(insn);
+    else
+      return NULL;
   }
   template <typename T>
   INLINE T &cast(Instruction &insn) {
-    GBE_ASSERTM(insn.isMemberOf<T>() == true, "Invalid instruction cast");
+    GBE_ASSERTM(insn.isMemberOf<T>() == true, "Invalid instruction type");
     return reinterpret_cast<T&>(insn);
   }
   template <typename T>
   INLINE const T &cast(const Instruction &insn) {
-    GBE_ASSERTM(insn.isMemberOf<T>() == true, "Invalid instruction cast");
+    GBE_ASSERTM(insn.isMemberOf<T>() == true, "Invalid instruction type");
     return reinterpret_cast<const T&>(insn);
   }
 
diff --git a/backend/src/ir/opt_local_remove_foo_mov.cpp b/backend/src/ir/opt_local_remove_foo_mov.cpp
new file mode 100644 (file)
index 0000000..c3a48bf
--- /dev/null
@@ -0,0 +1,27 @@
+/* 
+ * Copyright © 2012 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Benjamin Segovia <benjamin.segovia@intel.com>
+ */
+
+/**
+ * \file llvm_gen_backend.cpp
+ * \author Benjamin Segovia <benjamin.segovia@intel.com>
+ *
+ * Somehow a ad-hoc pass to remove the extra moves introduced by LLVM to Gen IR
+ * pass
+ */
+
index 4f40ed8..e50d543 100644 (file)
@@ -32,17 +32,17 @@ namespace ir {
   {
     static void init(Function &fn) {
       IF_DEBUG(Register r);
-      IF_DEBUG(r =) fn.newRegister(RegisterData::DWORD);
+      IF_DEBUG(r =) fn.newRegister(FAMILY_DWORD);
       GBE_ASSERT(r == lid0);
-      IF_DEBUG(r =) fn.newRegister(RegisterData::DWORD);
+      IF_DEBUG(r =) fn.newRegister(FAMILY_DWORD);
       GBE_ASSERT(r == lid1);
-      IF_DEBUG(r =) fn.newRegister(RegisterData::DWORD);
+      IF_DEBUG(r =) fn.newRegister(FAMILY_DWORD);
       GBE_ASSERT(r == lid2);
-      IF_DEBUG(r =) fn.newRegister(RegisterData::DWORD);
+      IF_DEBUG(r =) fn.newRegister(FAMILY_DWORD);
       GBE_ASSERT(r == gid0);
-      IF_DEBUG(r =) fn.newRegister(RegisterData::DWORD);
+      IF_DEBUG(r =) fn.newRegister(FAMILY_DWORD);
       GBE_ASSERT(r == gid1);
-      IF_DEBUG(r =) fn.newRegister(RegisterData::DWORD);
+      IF_DEBUG(r =) fn.newRegister(FAMILY_DWORD);
       GBE_ASSERT(r == gid2);
     }
   } /* namespace ocl */
index fa00f83..d2d7b02 100644 (file)
@@ -30,11 +30,11 @@ namespace ir {
   std::ostream &operator<< (std::ostream &out, const RegisterData &regData)
   {
     switch (regData.family) {
-      case RegisterData::BOOL: return out << "bool";
-      case RegisterData::BYTE: return out << "byte";
-      case RegisterData::WORD: return out << "word";
-      case RegisterData::DWORD: return out << "dword";
-      case RegisterData::QWORD: return out << "qword";
+      case FAMILY_BOOL: return out << "bool";
+      case FAMILY_BYTE: return out << "byte";
+      case FAMILY_WORD: return out << "word";
+      case FAMILY_DWORD: return out << "dword";
+      case FAMILY_QWORD: return out << "qword";
     };
     return out;
   }
index 94d90e3..00afff4 100644 (file)
 namespace gbe {
 namespace ir {
 
+  /*! Basically provides the size of the register */
+  enum RegisterFamily : uint8_t {
+    FAMILY_BOOL  = 0,
+    FAMILY_BYTE  = 1,
+    FAMILY_WORD  = 2,
+    FAMILY_DWORD = 3,
+    FAMILY_QWORD = 4
+  };
+
   /*! A register can be either a byte, a word, a dword or a qword. We store this
    *  value into a register data (which makes the register file) 
    */
   class RegisterData
   {
   public:
-    /*! RegisterData family */
-    enum Family : uint8_t {
-      BOOL  = 0,
-      BYTE  = 1,
-      WORD  = 2,
-      DWORD = 3,
-      QWORD = 4
-    };
     /*! Build a register. All fields will be immutable */
-    INLINE RegisterData(Family family = DWORD) : family(family) {}
+    INLINE RegisterData(RegisterFamily family = FAMILY_DWORD) : family(family) {}
     /*! Copy constructor */
     INLINE RegisterData(const RegisterData &other) : family(other.family) {}
     /*! Copy operator */
@@ -55,7 +56,7 @@ namespace ir {
     }
     /*! Nothing really happens here */
     INLINE ~RegisterData(void) {}
-    Family family;
+    RegisterFamily family;
     GBE_CLASS(RegisterData);
   };
 
@@ -79,7 +80,7 @@ namespace ir {
   {
   public:
     /*! Return the index of a newly allocated register */
-    INLINE Register append(RegisterData::Family family) {
+    INLINE Register append(RegisterFamily family) {
       GBE_ASSERTM(regNum() <= MAX_INDEX,
                   "Too many defined registers (only 65536 are supported)");
       const uint16_t index = regNum();
index 56f24d2..1e24906 100644 (file)
@@ -53,37 +53,37 @@ namespace ir {
   std::ostream &operator<< (std::ostream &out, const Type &type);
 
   /*! Get the register family for each type */
-  INLINE RegisterData::Family getFamily(Type type) {
+  INLINE RegisterFamily getFamily(Type type) {
     switch (type) {
       case TYPE_BOOL:
-        return RegisterData::BOOL;
+        return FAMILY_BOOL;
       case TYPE_S8:
       case TYPE_U8:
-        return RegisterData::BYTE;
+        return FAMILY_BYTE;
       case TYPE_S16:
       case TYPE_U16:
       case TYPE_HALF:
-        return RegisterData::WORD;
+        return FAMILY_WORD;
       case TYPE_S32:
       case TYPE_U32:
       case TYPE_FLOAT:
-        return RegisterData::DWORD;
+        return FAMILY_DWORD;
       case TYPE_S64:
       case TYPE_U64:
       case TYPE_DOUBLE:
-        return RegisterData::QWORD;
+        return FAMILY_QWORD;
     };
-    return RegisterData::DWORD;
+    return FAMILY_DWORD;
   }
 
   /*! Return a type for each register family */
-  INLINE Type getType(RegisterData::Family family) {
+  INLINE Type getType(RegisterFamily family) {
     switch (family) {
-      case RegisterData::BOOL: return TYPE_BOOL;
-      case RegisterData::BYTE: return TYPE_U8;
-      case RegisterData::WORD: return TYPE_U16;
-      case RegisterData::DWORD: return TYPE_U32;
-      case RegisterData::QWORD: return TYPE_U64;
+      case FAMILY_BOOL: return TYPE_BOOL;
+      case FAMILY_BYTE: return TYPE_U8;
+      case FAMILY_WORD: return TYPE_U16;
+      case FAMILY_DWORD: return TYPE_U32;
+      case FAMILY_QWORD: return TYPE_U64;
     };
     return TYPE_U32;
   }
index bd9e0fa..956722f 100644 (file)
@@ -115,25 +115,25 @@ namespace gbe
   }
 
   /*! Type to register family translation */
-  static ir::RegisterData::Family getFamily(const ir::Context &ctx, const Type *type)
+  static ir::RegisterFamily getFamily(const ir::Context &ctx, const Type *type)
   {
     GBE_ASSERT(isScalarType(type) == true); 
     if (type == Type::getInt1Ty(type->getContext()))
-      return ir::RegisterData::BOOL;
+      return ir::FAMILY_BOOL;
     if (type == Type::getInt8Ty(type->getContext()))
-      return ir::RegisterData::BYTE;
+      return ir::FAMILY_BYTE;
     if (type == Type::getInt16Ty(type->getContext()))
-      return ir::RegisterData::WORD;
+      return ir::FAMILY_WORD;
     if (type == Type::getInt32Ty(type->getContext()) || type->isFloatTy())
-      return ir::RegisterData::DWORD;
+      return ir::FAMILY_DWORD;
     if (type == Type::getInt64Ty(type->getContext()) || type->isDoubleTy())
-      return ir::RegisterData::QWORD;
+      return ir::FAMILY_QWORD;
     if (type->isPointerTy() && ctx.getPointerSize() == ir::POINTER_32_BITS)
-      return ir::RegisterData::DWORD;
+      return ir::FAMILY_DWORD;
     if (type->isPointerTy() && ctx.getPointerSize() == ir::POINTER_64_BITS)
-      return ir::RegisterData::QWORD;
+      return ir::FAMILY_QWORD;
     GBE_ASSERT(0);
-    return ir::RegisterData::BOOL;
+    return ir::FAMILY_BOOL;
   }
 
   /*! Get number of element to process dealing either with a vector or a scalar
@@ -248,7 +248,7 @@ namespace gbe
      *  the value is a vector of scalars)
      */
     ir::Register newScalar(Value *value, Type *type, uint32_t index) {
-      const ir::RegisterData::Family family = getFamily(ctx, type);
+      const ir::RegisterFamily family = getFamily(ctx, type);
       const ir::Register reg = ctx.reg(family);
       this->insertRegister(reg, value, index);
       return reg;
@@ -569,16 +569,7 @@ namespace gbe
   void GenWriter::emitBasicBlock(BasicBlock *BB) {
     GBE_ASSERT(labelMap.find(BB) != labelMap.end());
     ctx.LABEL(labelMap[BB]);
-    for (auto II = BB->begin(), E = BB->end(); II != E; ++II) {
-      const Type *Ty = II->getType();
-      GBE_ASSERT(!Ty->isIntegerTy() ||
-          (Ty==Type::getInt1Ty(II->getContext())  ||
-           Ty==Type::getInt8Ty(II->getContext())  ||
-           Ty==Type::getInt16Ty(II->getContext()) ||
-           Ty==Type::getInt32Ty(II->getContext()) ||
-           Ty==Type::getInt64Ty(II->getContext())));
-      visit(*II);
-    }
+    for (auto II = BB->begin(), E = BB->end(); II != E; ++II) visit(*II);
   }
 
   void GenWriter::emitMovForPHI(BasicBlock *curr, BasicBlock *succ) {
@@ -595,7 +586,7 @@ namespace gbe
         // will remove them
         for (uint32_t elemID = 0; elemID < elemNum; ++elemID) {
           const ir::Register dst = this->getRegister(PN, elemID);
-          const ir::Register src = this->getRegister(PN->getOperand(0), elemID);
+          const ir::Register src = this->getRegister(IV, elemID);
           ctx.MOV(type, dst, src);
         }
       }
@@ -628,7 +619,7 @@ namespace gbe
     if (!returnStruct) {
       const Type *type = F.getReturnType();
       if (type->isVoidTy() == false) {
-        const ir::RegisterData::Family family = getFamily(ctx, type);
+        const ir::RegisterFamily family = getFamily(ctx, type);
         const ir::Register reg = ctx.reg(family);
         ctx.output(reg);
       }
@@ -687,7 +678,7 @@ namespace gbe
     if (fn.outputNum() == 1 && I.getNumOperands() > 0) {
       const ir::Register dst = fn.getOutput(0);
       const ir::Register src = this->getRegister(I.getOperand(0));
-      const ir::RegisterData::Family family = fn.getRegisterFamiy(dst);;
+      const ir::RegisterFamily family = fn.getRegisterFamiy(dst);;
       ctx.MOV(ir::getType(family), dst, src);
     }
     ctx.RET();
index ae54ed0..624aad4 100644 (file)
@@ -214,7 +214,7 @@ namespace gbe
     {
       friend class GrowingPool;
       GrowingPoolElem(size_t elemNum) {
-        const size_t sz = min(sizeof(T), sizeof(void*));
+        const size_t sz = max(sizeof(T), sizeof(void*));
         this->data = (T*) GBE_ALIGNED_MALLOC(elemNum * sz, AlignOf<T>::value);
         this->next = NULL;
         this->maxElemNum = elemNum;
index 34c4eba..8265519 100644 (file)
@@ -40,9 +40,9 @@ namespace gbe
     Unit unit;
     Context ctx(unit);
     ctx.startFunction("hop");
-      const Register reg0 = ctx.reg(RegisterData::DWORD);
-      const Register reg1 = ctx.reg(RegisterData::DWORD);
-      const Register reg2 = ctx.reg(RegisterData::DWORD);
+      const Register reg0 = ctx.reg(FAMILY_DWORD);
+      const Register reg1 = ctx.reg(FAMILY_DWORD);
+      const Register reg2 = ctx.reg(FAMILY_DWORD);
       ctx.MAD(TYPE_FLOAT, reg0, reg0, reg1, reg2);
     ctx.endFunction();
   }
@@ -55,9 +55,9 @@ namespace gbe
     Unit unit;
     Context ctx(unit);
     ctx.startFunction("hop");
-      const Register reg0 = ctx.reg(RegisterData::DWORD);
-      const Register reg1 = ctx.reg(RegisterData::DWORD);
-      const Register reg2 = ctx.reg(RegisterData::DWORD);
+      const Register reg0 = ctx.reg(FAMILY_DWORD);
+      const Register reg1 = ctx.reg(FAMILY_DWORD);
+      const Register reg2 = ctx.reg(FAMILY_DWORD);
       ctx.MAD(TYPE_FLOAT, reg0, reg0, reg1, reg2);
       ctx.startFunction("bip");
         const LabelIndex label = ctx.label();
index a1a2d5a..9ecc145 100644 (file)
@@ -76,8 +76,8 @@ runTests:
   GBE_ASSERT(dummyKernel != NULL);
   fclose(dummyKernel);
 
-  UTEST_EXPECT_SUCCESS(utestLLVM2Gen("function_param.ll"));
-  //UTEST_EXPECT_SUCCESS(utestLLVM2Gen("loop.ll"));
+  //UTEST_EXPECT_SUCCESS(utestLLVM2Gen("function_param.ll"));
+  UTEST_EXPECT_SUCCESS(utestLLVM2Gen("loop.ll"));
   //UTEST_EXPECT_SUCCESS(utestLLVM2Gen("mad.ll"));
 #if 0
   UTEST_EXPECT_SUCCESS(utestLLVM2Gen("select.ll"));