Added type safety for all uint* Added one more test
authorBenjamin Segovia <segovia.benjamin@gmail.com>
Fri, 17 Feb 2012 08:27:01 +0000 (08:27 +0000)
committerKeith Packard <keithp@keithp.com>
Fri, 10 Aug 2012 23:15:19 +0000 (16:15 -0700)
backend/src/CMakeLists.txt
backend/src/ir/function.cpp
backend/src/ir/function.hpp
backend/src/ir/instruction.cpp
backend/src/ir/instruction.hpp
backend/src/ir/register.hpp
backend/src/ir/value.hpp
backend/src/sys/alloc.cpp
backend/src/sys/alloc.hpp
backend/src/sys/platform.hpp
backend/src/utest/tester.cpp

index 87f2107..3b61e1e 100644 (file)
@@ -38,6 +38,7 @@ else (GBE_USE_BLOB)
     set (GBE_SRC
       ${GBE_SRC}
       utest/utest_test_utest.cpp
+      utest/utest_context.cpp
       utest/utest.cpp
       utest/utest.hpp)
   endif (GBE_COMPILE_UTEST)
index 7dd1588..a319dba 100644 (file)
@@ -35,7 +35,7 @@ namespace ir {
   BasicBlock::BasicBlock(Function &fn) : fn(fn) {}
   BasicBlock::~BasicBlock(void) {
     for (auto it = instructions.begin(); it != instructions.end(); ++it)
-      GBE_DELETE(*it);
+      fn.deleteInstruction(*it);
   }
 
 } /* namespace ir */
index ed7be14..2c1d02a 100644 (file)
@@ -41,21 +41,21 @@ namespace ir {
    */
   class BasicBlock
   {
-    public:
-      /*! Empty basic block */
-      BasicBlock(Function &fn);
-      /*! 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(); }
-    private:
-      friend class Function;           //!< Owns the basic blocks
-      list<Instruction*> instructions; //!< Sequence of instructions in the block
-      Function &fn;                    //!< Function the block belongs to
+  public:
+    /*! Empty basic block */
+    BasicBlock(Function &fn);
+    /*! 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(); }
+  private:
+    friend class Function;           //!< Owns the basic blocks
+    list<Instruction*> instructions; //!< Sequence of instructions in the block
+    Function &fn;                    //!< Function the block belongs to
   };
 
   /*! A function is no more that a set of declared registers and a set of
@@ -75,9 +75,9 @@ namespace ir {
       return file.get(ID, which);
     }
     /*! Get the given value ie immediate from the function */
-    INLINE Value getValue(uint32_t ID) const {
-      GBE_ASSERT(ID < values.size());
-      return values[ID];
+    INLINE Immediate getImmediate(uint32_t ID) const {
+      GBE_ASSERT(ID < immediates.size());
+      return immediates[ID];
     }
     /*! Allocate a new instruction (with the growing pool) */
     INLINE Instruction *newInstruction(void) {
@@ -94,16 +94,16 @@ namespace ir {
     /*! Number of labels in the function */
     INLINE uint32_t labelNum(void) const { return labels.size(); }
     /*! Number of immediate values in the function */
-    INLINE uint32_t valueNum(void) const { return values.size(); }
+    INLINE uint32_t immediateNum(void) const { return immediates.size(); }
 
   private:
-    friend class Context;         //!< Can freely modify a function
-    vector<RegisterIndex> input;  //!< Input registers of the function
-    vector<RegisterIndex> output; //!< Output registers of the function
-    vector<BasicBlock*> labels;   //!< Each label points to a basic block
-    vector<Value> values;         //!< All immediate values in the function
-    vector<BasicBlock*> blocks;   //!< All chained basic blocks
-    RegisterFile file;            //!< Registers used by the instructions
+    friend class Context;          //!< Can freely modify a function
+    vector<RegisterIndex> input;   //!< Input registers of the function
+    vector<RegisterIndex> output;  //!< Output registers of the function
+    vector<BasicBlock*> labels;    //!< Each label points to a basic block
+    vector<Immediate> immediates;  //!< All immediate values in the function
+    vector<BasicBlock*> blocks;    //!< All chained basic blocks
+    RegisterFile file;             //!< Registers used by the instructions
     GrowingPool<Instruction> insnPool; //!< For fast instruction allocation
     GBE_CLASS(Function);
   };
index f16975a..31bb874 100644 (file)
@@ -313,14 +313,17 @@ namespace ir {
     class LoadImmInstruction : public BasePolicy, public NoSrcPolicy
     {
     public:
-      INLINE LoadImmInstruction(Type type, RegisterIndex dst, ValueIndex valueIndex) {
+      INLINE LoadImmInstruction(Type type,
+                                RegisterIndex dst,
+                                ImmediateIndex immediateIndex)
+      {
         this->dst = dst;
         this->opcode = OP_LOADI;
-        this->valueIndex = valueIndex;
+        this->immediateIndex = immediateIndex;
         this->type = type;
       }
-      INLINE Value getValue(const Function &fn) const {
-        return fn.getValue(valueIndex);
+      INLINE Immediate getImmediate(const Function &fn) const {
+        return fn.getImmediate(immediateIndex);
       }
       INLINE uint32_t getDstNum(void) const{ return 1; }
       INLINE RegisterIndex getDstIndex(const Function &fn, uint32_t ID) const {
@@ -329,9 +332,9 @@ namespace ir {
       }
       INLINE Type getType(void) const { return this->type; }
       bool wellFormed(const Function &fn, std::string &why) const;
-      RegisterIndex dst;    //!< Register to store into
-      ValueIndex valueIndex;//!< Index in the vector of immediates
-      Type type;            //!< Type of the immediate
+      RegisterIndex dst;              //!< Register to store into
+      ImmediateIndex immediateIndex;  //!< Index in the vector of immediates
+      Type type;                      //!< Type of the immediate
     };
 
     class FenceInstruction : public BasePolicy, public NoSrcPolicy, public NoDstPolicy
@@ -479,11 +482,11 @@ namespace ir {
     // Ensure that types and register family match
     INLINE bool LoadImmInstruction::wellFormed(const Function &fn, std::string &whyNot) const
     {
-      if (UNLIKELY(valueIndex >= fn.valueNum())) {
+      if (UNLIKELY(immediateIndex >= fn.immediateNum())) {
         whyNot = "Out-of-bound immediate value index";
         return false;
       }
-      if (UNLIKELY(type != fn.getValue(valueIndex).type)) {
+      if (UNLIKELY(type != fn.getImmediate(immediateIndex).type)) {
         whyNot = "Inconsistant type for the immediate value to load";
         return false;
       }
@@ -679,7 +682,7 @@ DECL_MEM_FN(StoreInstruction, MemorySpace, getAddressSpace(void), getAddressSpac
 DECL_MEM_FN(LoadInstruction, Type, getValueType(void), getValueType())
 DECL_MEM_FN(LoadInstruction, uint32_t, getValueNum(void), getValueNum())
 DECL_MEM_FN(LoadInstruction, MemorySpace, getAddressSpace(void), getAddressSpace())
-DECL_MEM_FN(LoadImmInstruction, Value, getValue(const Function &fn), getValue(fn))
+DECL_MEM_FN(LoadImmInstruction, Immediate, getImmediate(const Function &fn), getImmediate(fn))
 DECL_MEM_FN(LoadImmInstruction, Type, getType(void), getType())
 DECL_MEM_FN(BranchInstruction, bool, isPredicated(void), isPredicated())
 
@@ -765,7 +768,7 @@ DECL_MEM_FN(BranchInstruction, bool, isPredicated(void), isPredicated())
   }
 
   // LOADI
-  Instruction LOADI(Type type, RegisterIndex dst, ValueIndex value) {
+  Instruction LOADI(Type type, RegisterIndex dst, ImmediateIndex value) {
     internal::LoadImmInstruction insn(type, dst, value);
     return insn.convert();
   }
index 2977e13..3190f25 100644 (file)
@@ -19,7 +19,6 @@
 
 /**
  * \file instruction.hpp
- *
  * \author Benjamin Segovia <benjamin.segovia@intel.com>
  */
 #ifndef __GBE_IR_INSTRUCTION_HPP__
@@ -49,10 +48,10 @@ namespace ir {
   };
 
   /*! A label is identified with an unsigned short */
-  typedef uint16_t LabelIndex;
+  TYPE_SAFE(LabelIndex, uint16_t)
 
   /*! A value is stored in a per-function vector. This is the index to it */
-  typedef uint16_t ValueIndex;
+  TYPE_SAFE(ImmediateIndex, uint16_t)
 
   /*! Function class contains the register file and the register tuple. Any
    *  information related to the registers may therefore require a function
@@ -209,7 +208,7 @@ namespace ir {
   class LoadImmInstruction : public Instruction {
   public:
     /*! Return the value stored in the instruction */
-    Value getValue(const Function &fn) const;
+    Immediate getImmediate(const Function &fn) const;
     /*! Return the type of the stored value */
     Type getType(void) const;
     /*! Return true if the given instruction is an instance of this class */
@@ -343,7 +342,7 @@ namespace ir {
   /*! (pred) bra labelIndex */
   Instruction BRA(LabelIndex labelIndex, RegisterIndex pred);
   /*! loadi.type dst value */
-  Instruction LOADI(Type type, RegisterIndex dst, ValueIndex value);
+  Instruction LOADI(Type type, RegisterIndex dst, ImmediateIndex value);
   /*! load.type.space {dst1,...,dst_valueNum} offset value */
   Instruction LOAD(Type type, TupleIndex dst, RegisterIndex offset, MemorySpace space, uint16_t valueNum);
   /*! store.type.space offset {src1,...,src_valueNum} value */
index c2dd066..0123dad 100644 (file)
@@ -61,30 +61,12 @@ namespace ir {
   /*! 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;
-  };
+  TYPE_SAFE(RegisterIndex, uint16_t)
 
   /*! 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;
-  };
+  TYPE_SAFE(TupleIndex, uint16_t)
 
   /*! A register file allocates and destroys registers. Basically, we will have
    *  one register file per function
index a66081c..f5aa72e 100644 (file)
@@ -32,13 +32,14 @@ namespace gbe {
 namespace ir {
 
   /*! The value as stored in the instruction */
-  class Value
+  class Immediate
   {
   public:
 #define DECL_CONSTRUCTOR(TYPE, FIELD) \
-    Value(TYPE FIELD) { this->data.u64 = 0llu; this->data.FIELD = FIELD; }
-    DECL_CONSTRUCTOR(int8_t, s8);
-    DECL_CONSTRUCTOR(uint8_t, u8);
+    Immediate(TYPE FIELD) { this->data.u64 = 0llu; this->data.FIELD = FIELD; }
+    DECL_CONSTRUCTOR(int8_t, s8)
+    DECL_CONSTRUCTOR(uint8_t, u8)
+#undef DECL_CONSTRUCTOR
     union {
       int8_t s8;
       uint8_t u8;
@@ -52,7 +53,6 @@ namespace ir {
       double f64;
     } data;     //!< Value to store
     Type type;  //!< Type of the value
-#undef DECL_CONSTRUCTOR
   };
 
 } /* namespace ir */
index 55a315e..af4d390 100644 (file)
@@ -146,12 +146,17 @@ namespace gbe
     delete _debug;
   }
 
-  /*! Use this to serialize multiple starts of the debugger */
-  static MutexSys startMemDebuggerMutex;
+  /*! Bring up the debugger at pre-main */
+  static struct ForceMemDebugger {
+    ForceMemDebugger(void) {
+      doesnotmatter = GBE_NEW(int);
+      GBE_DELETE(doesnotmatter);
+    }
+    int *doesnotmatter;
+  } forceMemDebugger;
 
   /*! Start the memory debugger */
   static void MemDebuggerStart(void) {
-    Lock<MutexSys> lock(startMemDebuggerMutex);
     if (memDebugger == NULL) {
       atexit(MemDebuggerEnd);
       memDebugger = new MemDebugger;
@@ -223,12 +228,12 @@ namespace gbe
     if (ptr) {
       const size_t size = ((uintptr_t*)ptr)[-2];
       MemDebuggerInitializeMem(ptr, size);
-      free(((void**)ptr)[-2]);
+      free(((void**)ptr)[-1]);
     }
   }
 } /* namespace gbe */
 
-#else
+#else /* GBE_DEBUG_MEMORY */
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Windows Platform
index 58aa8a4..ed1e346 100644 (file)
@@ -214,15 +214,14 @@ namespace gbe
     {
       friend class GrowingPool;
       GrowingPoolElem(size_t elemNum) {
-        const size_t sz = min(sizeof(T), 2 * sizeof(void*));
+        const size_t sz = min(sizeof(T), sizeof(void*));
         this->data = (T*) GBE_ALIGNED_MALLOC(elemNum * sz, AlignOf<T>::value);
         this->next = NULL;
         this->maxElemNum = elemNum;
         this->allocated = 0;
       }
       ~GrowingPoolElem(void) {
-        GBE_ASSERT(this->data);
-        GBE_DELETE_ARRAY(this->data);
+        GBE_ALIGNED_FREE(this->data);
         if (this->next) GBE_DELETE(this->next);
       }
       T *data;
index d4c451e..88f217e 100644 (file)
@@ -237,6 +237,19 @@ do {                                                 \
 /*! Produce a string from the macro locatiom */
 #define HERE (STRING(__LINE__) "@" __FILE__)
 
+/*! Typesafe encapusalation of a type (mostly for integers) */
+#define TYPE_SAFE(SAFE, UNSAFE)                                     \
+class SAFE                                                          \
+{                                                                   \
+public:                                                             \
+  INLINE SAFE(void) {}                                              \
+  explicit INLINE SAFE(uint16_t unsafe) : unsafe(unsafe) {}         \
+  INLINE operator UNSAFE (void) const { return unsafe; }            \
+  UNSAFE value(void) const { return unsafe; }                       \
+private:                                                            \
+  UNSAFE unsafe;                                                    \
+};
+
 /*! Portable AlignOf */
 template <typename T>
 struct AlignOf
index 5fcb947..ffbb915 100644 (file)
@@ -30,8 +30,8 @@ int main(int argc, char *argv[])
   using namespace gbe;
 
   // Run the unit tests specified by the user
-  if (argc > 2)
-    for (int i = 2; i < argc; ++i)
+  if (argc >= 2)
+    for (int i = 1; i < argc; ++i)
       UTest::run(argv[i]);
   else
     UTest::runAll();