From 349ad6cde2789e7000ce345cacc8d296c0296301 Mon Sep 17 00:00:00 2001 From: Benjamin Segovia Date: Fri, 17 Feb 2012 04:02:11 +0000 Subject: [PATCH] Added missing function for compares --- backend/src/ir/context.cpp | 30 ++++++++++++++++++++- backend/src/ir/context.hpp | 26 ++++++++++++------- backend/src/ir/function.cpp | 8 +++++- backend/src/ir/function.hpp | 59 ++++++++++++++++++++++++++++-------------- backend/src/ir/instruction.cpp | 18 +++++++++++++ backend/src/ir/instruction.hpp | 14 +++++----- backend/src/sys/alloc.hpp | 1 + 7 files changed, 118 insertions(+), 38 deletions(-) diff --git a/backend/src/ir/context.cpp b/backend/src/ir/context.cpp index 074b7ad..0d53865 100644 --- a/backend/src/ir/context.cpp +++ b/backend/src/ir/context.cpp @@ -19,7 +19,6 @@ /** * \file context.cpp - * * \author Benjamin Segovia */ #include "ir/context.hpp" @@ -59,6 +58,35 @@ namespace ir { fn->output.push_back(reg); } + void Context::startBlock(void) { + GBE_ASSERT(fn != NULL); + this->bb = GBE_NEW(BasicBlock, *fn); + fn->blocks.push_back(bb); + } + + void Context::endBlock(void) { + this->bb = NULL; + } + + void Context::append(const Instruction &insn) { + + // Start a new block if this is a label + if (insn.isMemberOf() == true) { + this->endBlock(); + this->startBlock(); + } + + // Append the instruction in the stream + GBE_ASSERT(fn != NULL && bb != NULL); + Instruction *insnPtr = fn->newInstruction(); + *insnPtr = insn; + bb->append(*insnPtr); + + // Close the current block if this is a branch + if (insn.isMemberOf() == true) + this->endBlock(); + } + } /* namespace ir */ } /* namespace gbe */ diff --git a/backend/src/ir/context.hpp b/backend/src/ir/context.hpp index afdee73..77db759 100644 --- a/backend/src/ir/context.hpp +++ b/backend/src/ir/context.hpp @@ -19,7 +19,6 @@ /** * \file context.hpp - * * \author Benjamin Segovia */ #ifndef __GBE_IR_CONTEXT_HPP__ @@ -94,14 +93,23 @@ namespace ir { this->STORE(type, index, offset, space, valueNum); } +#define DECL_CMP(NAME) \ + void NAME(Type type, \ + RegisterIndex dst, \ + RegisterIndex src0, \ + RegisterIndex src1) \ + { \ + this->CMP(type, CMP_##NAME, dst, src0, src1); \ + } +DECL_CMP(EQ) +DECL_CMP(NE) +DECL_CMP(LT) +DECL_CMP(LE) +DECL_CMP(GT) +DECL_CMP(GE) +#undef DECL_CMP + private: - /*! Check out-of-bound arguments */ - template void outOfBoundCheck(const T &t); - /*! Recurse on the arguments to check their correctness */ - template - INLINE void argumentCheck(First first, Rest... rest); - /*! Stop the argument checking */ - INLINE void argumentCheck(void); /*! A block must be started with a label */ void startBlock(void); /*! A block must be ended with a branch */ @@ -110,7 +118,7 @@ namespace ir { void append(const Instruction &insn); Unit &unit; //!< A unit is associated to a contect Function *fn; //!< Current function we are processing - Function::BasicBlock *bb; //!< Current basic block we are filling + BasicBlock *bb; //!< Current basic block we are filling vector fnStack;//!< Stack of functions still to finish }; diff --git a/backend/src/ir/function.cpp b/backend/src/ir/function.cpp index 6f6d353..7dd1588 100644 --- a/backend/src/ir/function.cpp +++ b/backend/src/ir/function.cpp @@ -29,7 +29,13 @@ namespace ir { Function::Function(void) {} Function::~Function(void) { - for (auto it = bb.begin(); it != bb.end(); ++it) GBE_DELETE(*it); + for (auto it = blocks.begin(); it != blocks.end(); ++it) + GBE_DELETE(*it); + } + BasicBlock::BasicBlock(Function &fn) : fn(fn) {} + BasicBlock::~BasicBlock(void) { + for (auto it = instructions.begin(); it != instructions.end(); ++it) + GBE_DELETE(*it); } } /* namespace ir */ diff --git a/backend/src/ir/function.hpp b/backend/src/ir/function.hpp index 45434e8..0e894d3 100644 --- a/backend/src/ir/function.hpp +++ b/backend/src/ir/function.hpp @@ -29,10 +29,36 @@ #include "ir/register.hpp" #include "ir/instruction.hpp" #include "sys/vector.hpp" +#include "sys/list.hpp" +#include "sys/alloc.hpp" namespace gbe { namespace ir { + /*! Function basic blocks really belong to a function since: + * 1 - registers used in the basic blocks belongs to the function register + * file + * 2 - branches point to basic blocks of the same function + */ + 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 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 * basic blocks */ @@ -43,23 +69,6 @@ namespace ir { Function(void); /*! Release everything *including* the basic block pointers */ ~Function(void); - - /*! Function basic blocks really belong to a function since: - * 1 - registers used in the basic blocks belongs to the function register - * file - * 2 - branches point to basic blocks of the same function - */ - class BasicBlock - { - public: - /*! Empty basic block */ - BasicBlock(void); - /*! Return the number of instruction in the block */ - INLINE uint32_t getInsnNum(void) { return insn.size(); } - private: - vector insn; //!< Sequence of instructions in the block - }; - /*! Extract the register from the register file */ INLINE Register getRegister(RegisterIndex ID) const { return file.get(ID); } /*! Get the register index from the tuple vector */ @@ -71,6 +80,14 @@ namespace ir { GBE_ASSERT(ID < values.size()); return values[ID]; } + /*! Allocate a new instruction (with the growing pool) */ + INLINE Instruction *newInstruction(void) { + return insnPool.allocate(); + } + /*! Deallocate an instruction (with the growing pool) */ + INLINE void deleteInstruction(Instruction *insn) { + insnPool.deallocate(insn); + } /*! Number of registers in the register file */ INLINE uint32_t regNum(void) const { return file.regNum(); } /*! Number of register tuples in the register file */ @@ -85,9 +102,11 @@ namespace ir { vector input; //!< Input registers of the function vector output; //!< Output registers of the function vector labels; //!< Each label points to a basic block - vector values; //!< All immediate values stored in the function - vector bb; //!< All the basic blocks one after the others - RegisterFile file; //!< All the registers used in the instructions + vector values; //!< All immediate values in the function + vector blocks; //!< All chained basic blocks + RegisterFile file; //!< Registers used by the instructions + GrowingPool insnPool; //!< For fast instruction allocation + GBE_CLASS(Function); }; } /* namespace ir */ diff --git a/backend/src/ir/instruction.cpp b/backend/src/ir/instruction.cpp index 306446d..f16975a 100644 --- a/backend/src/ir/instruction.cpp +++ b/backend/src/ir/instruction.cpp @@ -167,6 +167,7 @@ namespace ir { { this->operation = operation; } + INLINE CompareOperation getOperation(void) const { return operation; } INLINE bool wellFormed(const Function &fn, std::string &whyNot) const; CompareOperation operation; }; @@ -569,6 +570,10 @@ START_INTROSPECTION(TernaryInstruction) #include "ir/instruction.hxx" END_INTROSPECTION(TernaryInstruction) +START_INTROSPECTION(CompareInstruction) +#include "ir/instruction.hxx" +END_INTROSPECTION(CompareInstruction) + START_INTROSPECTION(ConvertInstruction) #include "ir/instruction.hxx" END_INTROSPECTION(ConvertInstruction) @@ -664,6 +669,8 @@ END_FUNCTION(Instruction, bool) DECL_MEM_FN(UnaryInstruction, Type, getType(void), getType()) DECL_MEM_FN(BinaryInstruction, Type, getType(void), getType()) DECL_MEM_FN(TernaryInstruction, Type, getType(void), getType()) +DECL_MEM_FN(CompareInstruction, Type, getType(void), getType()) +DECL_MEM_FN(CompareInstruction, CompareOperation, getOperation(void), getOperation()) DECL_MEM_FN(ConvertInstruction, Type, getSrcType(void), getSrcType()) DECL_MEM_FN(ConvertInstruction, Type, getDstType(void), getDstType()) DECL_MEM_FN(StoreInstruction, Type, getValueType(void), getValueType()) @@ -730,6 +737,17 @@ DECL_MEM_FN(BranchInstruction, bool, isPredicated(void), isPredicated()) return insn.convert(); } + // CMP + Instruction CMP(Type type, + CompareOperation operation, + RegisterIndex dst, + RegisterIndex src0, + RegisterIndex src1) + { + internal::CompareInstruction insn(type, operation, dst, src0, src1); + return insn.convert(); + } + // CVT Instruction CVT(Type dstType, Type srcType, RegisterIndex dst, RegisterIndex src) { internal::ConvertInstruction insn(dstType, srcType, dst, src); diff --git a/backend/src/ir/instruction.hpp b/backend/src/ir/instruction.hpp index f4c3015..2977e13 100644 --- a/backend/src/ir/instruction.hpp +++ b/backend/src/ir/instruction.hpp @@ -138,12 +138,12 @@ namespace ir { /*! Operation done in comparison */ enum CompareOperation : uint8_t { - EQ = 0, // == - NE, // != - LT, // < - LE, // <= - GT, // > - GE // >= + CMP_EQ = 0, // == + CMP_NE, // != + CMP_LT, // < + CMP_LE, // <= + CMP_GT, // > + CMP_GE // >= }; /*! Compare instructions compare anything from the same type and return a @@ -335,7 +335,7 @@ namespace ir { /*! mad.type dst {src0, src1, src2} == src */ Instruction MAD(Type type, RegisterIndex dst, TupleIndex src); /*! cmp.type.op dst src0 src1 */ - Instruction CMP(Type type, CompareInstruction op, RegisterIndex dst, RegisterIndex src0, RegisterIndex src1); + Instruction CMP(Type type, CompareOperation op, RegisterIndex dst, RegisterIndex src0, RegisterIndex src1); /*! cvt.{dstType <- srcType} dst src */ Instruction CVT(Type dstType, Type srcType, RegisterIndex dst, RegisterIndex src0, RegisterIndex src1); /*! bra labelIndex */ diff --git a/backend/src/sys/alloc.hpp b/backend/src/sys/alloc.hpp index ab587de..58aa8a4 100644 --- a/backend/src/sys/alloc.hpp +++ b/backend/src/sys/alloc.hpp @@ -193,6 +193,7 @@ namespace gbe if (this->freeList != NULL) { T *data = (T*) freeList; this->freeList = *(void**) freeList; + return data; } if (UNLIKELY(current->allocated == current->maxElemNum)) { GrowingPoolElem *elem = GBE_NEW(GrowingPoolElem, 2 * current->maxElemNum); -- 2.7.4