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);
}
// Append the instruction in the stream
Instruction *insnPtr = fn->newInstruction();
+
*insnPtr = insn;
#if GBE_DEBUG
std::string whyNot;
/*! 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);
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;
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;
}
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 */
/*! 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);
};
/*! 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 */
/*! 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 */
/*! 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)
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)
// 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())) {
// 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())) {
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);
// 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;
// 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))
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))
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;
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;
}
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"); \
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: \
*/
class Function;
+ /*! Contains the stream of instructions */
+ class BasicBlock;
+
///////////////////////////////////////////////////////////////////////////
/// All public instruction classes as manipulated by all public classes
///////////////////////////////////////////////////////////////////////////
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) {}
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
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 {
*/
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);
}
--- /dev/null
+/*
+ * 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
+ */
+
{
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 */
std::ostream &operator<< (std::ostream &out, const RegisterData ®Data)
{
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;
}
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 */
}
/*! Nothing really happens here */
INLINE ~RegisterData(void) {}
- Family family;
+ RegisterFamily family;
GBE_CLASS(RegisterData);
};
{
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();
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;
}
}
/*! 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
* 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;
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) {
// 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);
}
}
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);
}
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();
{
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;
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();
}
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();
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"));