From c8830424f2ae811a1fbc490c4752e156928b02c5 Mon Sep 17 00:00:00 2001 From: Yang Rong Date: Tue, 11 Mar 2014 14:43:51 +0800 Subject: [PATCH] Add SROA and GVN pass to default optLevel. SROA and GVN may introduce some integer type not support by backend. Remove this type assert in GenWrite, and found these types, set the unit to invalid. If unit is invalid, use optLevel 0, which not include SROA and GVN, and try again. Signed-off-by: Yang Rong Reviewed-by: Zhigang Gong --- backend/src/backend/program.cpp | 15 ++++++++++++--- backend/src/ir/context.cpp | 3 ++- backend/src/ir/unit.cpp | 2 +- backend/src/ir/unit.hpp | 4 +++- backend/src/llvm/llvm_gen_backend.cpp | 26 ++++++++++++++++++-------- backend/src/llvm/llvm_to_gen.cpp | 5 +++-- 6 files changed, 39 insertions(+), 16 deletions(-) diff --git a/backend/src/backend/program.cpp b/backend/src/backend/program.cpp index f656299..5fddd64 100644 --- a/backend/src/backend/program.cpp +++ b/backend/src/backend/program.cpp @@ -103,12 +103,21 @@ namespace gbe { BVAR(OCL_OUTPUT_GEN_IR, false); bool Program::buildFromLLVMFile(const char *fileName, std::string &error, int optLevel) { - ir::Unit unit; - if (llvmToGen(unit, fileName, optLevel) == false) { + ir::Unit *unit = new ir::Unit(); + if (llvmToGen(*unit, fileName, optLevel) == false) { error = std::string(fileName) + " not found"; return false; } - this->buildFromUnit(unit, error); + //If unit is not valid, maybe some thing don't support by backend, introduce by some passes + //use optLevel 0 to try again. + if(!unit->getValid()) { + delete unit; //clear unit + unit = new ir::Unit(); + llvmToGen(*unit, fileName, 0); //suppose file exists and llvmToGen will not return false. + } + assert(unit->getValid()); + this->buildFromUnit(*unit, error); + delete unit; return true; } diff --git a/backend/src/ir/context.cpp b/backend/src/ir/context.cpp index d6815e1..ff5c575 100644 --- a/backend/src/ir/context.cpp +++ b/backend/src/ir/context.cpp @@ -157,7 +157,8 @@ namespace ir { bb->append(*insnPtr); #if GBE_DEBUG std::string whyNot; - GBE_ASSERTM(insnPtr->wellFormed(whyNot), whyNot.c_str()); + if(getUnit().getValid()) + GBE_ASSERTM(insnPtr->wellFormed(whyNot), whyNot.c_str()); #endif /* GBE_DEBUG */ // Close the current block if this is a branch diff --git a/backend/src/ir/unit.cpp b/backend/src/ir/unit.cpp index 4aeffe9..4f9d740 100644 --- a/backend/src/ir/unit.cpp +++ b/backend/src/ir/unit.cpp @@ -27,7 +27,7 @@ namespace gbe { namespace ir { - Unit::Unit(PointerSize pointerSize) : pointerSize(pointerSize) {} + Unit::Unit(PointerSize pointerSize) : pointerSize(pointerSize), valid(true) {} Unit::~Unit(void) { for (const auto &pair : functions) GBE_DELETE(pair.second); } diff --git a/backend/src/ir/unit.hpp b/backend/src/ir/unit.hpp index d8eab79..adebd3f 100644 --- a/backend/src/ir/unit.hpp +++ b/backend/src/ir/unit.hpp @@ -72,12 +72,15 @@ namespace ir { ConstantSet& getConstantSet(void) { return constantSet; } /*! Return the constant set */ const ConstantSet& getConstantSet(void) const { return constantSet; } + void setValid(bool value) { valid = value; } + bool getValid() { return valid; } private: friend class ContextInterface; //!< Can free modify the unit hash_map functions; //!< All the defined functions ConstantSet constantSet; //!< All the constants defined in the unit PointerSize pointerSize; //!< Size shared by all pointers GBE_CLASS(Unit); + bool valid; }; /*! Output the unit string in the given stream */ @@ -87,4 +90,3 @@ namespace ir { } /* namespace gbe */ #endif /* __GBE_IR_UNIT_HPP__ */ - diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp index dcc1497..227ef09 100644 --- a/backend/src/llvm/llvm_gen_backend.cpp +++ b/backend/src/llvm/llvm_gen_backend.cpp @@ -178,7 +178,7 @@ namespace gbe } /*! LLVM IR Type to Gen IR type translation */ - static ir::Type getType(const ir::Context &ctx, const Type *type) + static ir::Type getType(ir::Context &ctx, const Type *type) { GBE_ASSERT(isScalarType(type)); if (type->isFloatTy() == true) @@ -202,12 +202,12 @@ namespace gbe return ir::TYPE_S32; if (type == Type::getInt64Ty(type->getContext())) return ir::TYPE_S64; - GBE_ASSERT(0); + ctx.getUnit().setValid(false); return ir::TYPE_S64; } /*! LLVM IR Type to Gen IR unsigned type translation */ - static ir::Type getUnsignedType(const ir::Context &ctx, const Type *type) + static ir::Type getUnsignedType(ir::Context &ctx, const Type *type) { GBE_ASSERT(type->isIntegerTy() == true); if (type == Type::getInt1Ty(type->getContext())) @@ -220,12 +220,12 @@ namespace gbe return ir::TYPE_U32; if (type == Type::getInt64Ty(type->getContext())) return ir::TYPE_U64; - GBE_ASSERT(0); + ctx.getUnit().setValid(false); return ir::TYPE_U64; } /*! Type to register family translation */ - static ir::RegisterFamily getFamily(const ir::Context &ctx, const Type *type) + static ir::RegisterFamily getFamily(ir::Context &ctx, const Type *type) { GBE_ASSERT(isScalarType(type) == true); if (type == Type::getInt1Ty(type->getContext())) @@ -240,14 +240,14 @@ namespace gbe return ir::FAMILY_QWORD; if (type->isPointerTy()) return ctx.getPointerFamily(); - GBE_ASSERT(0); + ctx.getUnit().setValid(false); return ir::FAMILY_BOOL; } /*! Get number of element to process dealing either with a vector or a scalar * value */ - static ir::Type getVectorInfo(const ir::Context &ctx, Type *llvmType, Value *value, uint32_t &elemNum, bool useUnsigned = false) + static ir::Type getVectorInfo(ir::Context &ctx, Type *llvmType, Value *value, uint32_t &elemNum, bool useUnsigned = false) { ir::Type type; if (llvmType->isVectorTy() == true) { @@ -810,7 +810,8 @@ namespace gbe const uint64_t u64 = CI->getZExtValue(); return doIt(u64); } else { - GBE_ASSERTM(false, "Unsupported integer size"); + //GBE_ASSERTM(false, "Unsupported integer size"); + doIt.invalid(); return doIt(uint64_t(0)); } } @@ -855,6 +856,9 @@ namespace gbe template ir::ImmediateIndex operator() (const T &t) { return ctx.newImmediate(t); } + void invalid() { + ctx.getUnit().setValid(false); + } ir::Context &ctx; }; @@ -1845,6 +1849,9 @@ namespace gbe template ir::Immediate operator() (const T &t) { return ir::Immediate(t); } + void invalid() { + ctx.getUnit().setValid(false); + } ir::Context &ctx; }; @@ -2188,6 +2195,9 @@ namespace gbe template INLINE uint64_t operator() (const T &t) { return uint64_t(t); } + void invalid() { + ctx.getUnit().setValid(false); + } ir::Context &ctx; }; diff --git a/backend/src/llvm/llvm_to_gen.cpp b/backend/src/llvm/llvm_to_gen.cpp index 8b2ac04..9e18a57 100644 --- a/backend/src/llvm/llvm_to_gen.cpp +++ b/backend/src/llvm/llvm_to_gen.cpp @@ -116,7 +116,8 @@ namespace gbe MPM.add(createFunctionAttrsPass()); // Set readonly/readnone attrs //MPM.add(createScalarReplAggregatesPass(64, true, -1, -1, 64)) - //MPM.add(createSROAPass(/*RequiresDomTree*/ false)); + if(optLevel > 0) + MPM.add(createSROAPass(/*RequiresDomTree*/ false)); MPM.add(createEarlyCSEPass()); // Catch trivial redundancies MPM.add(createJumpThreadingPass()); // Thread jumps. MPM.add(createCorrelatedValuePropagationPass()); // Propagate conditionals @@ -135,7 +136,7 @@ namespace gbe MPM.add(createLoopDeletionPass()); // Delete dead loops MPM.add(createLoopUnrollPass()); // Unroll small loops if(optLevel > 0) - MPM.add(createGVNPass(true)); // Remove redundancies + MPM.add(createGVNPass()); // Remove redundancies MPM.add(createMemCpyOptPass()); // Remove memcpy / form memset MPM.add(createSCCPPass()); // Constant prop with SCCP -- 2.7.4