/*! \brief Whether to disable select rewriting. */
bool disable_select_rewriting = false;
+ /*! \brief Whether to disable loop vectorization. */
+ bool disable_vectorize = false;
+
void VisitAttrs(AttrVisitor* v) final {
v->Visit("data_alignment", &data_alignment);
v->Visit("offset_factor", &offset_factor);
v->Visit("dump_pass_ir", &dump_pass_ir);
v->Visit("instrument_bound_checkers", &instrument_bound_checkers);
v->Visit("disable_select_rewriting", &disable_select_rewriting);
+ v->Visit("disable_vectorize", &disable_vectorize);
}
static constexpr const char* _type_key = "BuildConfig";
/*!
* \brief vectorize the constant loops
- * \param stmt The statment to be vectorized.
+ * \param stmt The statement to be vectorized.
* \return Transformed stmt.
*/
Stmt VectorizeLoop(Stmt stmt);
+/*!
+ * \brief convert vectorized loops into serialized loops
+ * \param stmt The statement to skip vectorization on.
+ * \return Transformed stmt.
+ */
+Stmt SkipVectorize(Stmt stmt);
+
/*!
* \brief instruments bound checkers.
-* \param stmt The statment to be instrumented.
-* \return Instrumented Stmt.
+* \param stmt The statement to be instrumented.
+* \return Instrumented stmt.
*/
Stmt InstrumentBoundCheckers(Stmt stmt);
/*!
* \brief Inject virtual thread loops into stmt.
- * \param stmt The statment to be transformed.
+ * \param stmt The statement to be transformed.
* \return Transformed stmt.
*/
Stmt InjectVirtualThread(Stmt stmt);
/*!
* \brief Inject prefetch instructions into stmt.
- * \param stmt The statment to be transformed.
+ * \param stmt The statement to be transformed.
* \return Transformed stmt.
*/
Stmt InjectPrefetch(Stmt stmt);
/*!
* \brief Inject double buffer into stmt.
- * \param stmt The statment to be transformed.
+ * \param stmt The statement to be transformed.
* \param split_loop Loop splitting factor.
* \return Transformed stmt.
*/
/*!
* \brief Inject copy intrinsics with optional pad.
*
- * \param stmt The statment to be transformed.
+ * \param stmt The statement to be transformed.
* \param pragma_key The pragma key for hint of copy.
* \param fintrin The function with signature
*
* Trying to share space between allocations to make
* a static allocation plan when possible.
*
- * \param stmt The stmt to be trasnformed
+ * \param stmt The stmt to be transformed
* \return Transformed stmt.
*/
Stmt StorageRewrite(Stmt stmt);
/*!
* \brief Detect and insert sync points to co-processor.
*
- * \param stmt The stmt to be trasnformed
+ * \param stmt The stmt to be transformed
* \return Transformed stmt.
*/
Stmt CoProcSync(Stmt stmt);
/*!
* \brief Lift common attrs with attr_key to outer scope.
*
- * \param stmt The stmt to be trasnformed
+ * \param stmt The stmt to be transformed
* \param attr_key The attribute key to be checked.
* \return Transformed stmt.
*/
/*!
* \brief Detect and rewrite unsafe select that contains memory access.
- * \param stmt The statment to be rewritten.
+ * \param stmt The statement to be rewritten.
* \return Transformed stmt.
*/
Stmt RewriteUnsafeSelect(Stmt stmt);
* \brief Lower attached storage access information.
* Do this pass after all storage access analysis finish.
*
- * \param stmt The stmt to be trasnformed
+ * \param stmt The stmt to be transformed
* \return Transformed stmt.
*/
Stmt LowerStorageAccessInfo(Stmt stmt);
* \brief Decorate the stmt with a device scope, this is helpful for
* hardware accelerator without thread blocks.
*
- * \param stmt The stmt to be trasnformed
+ * \param stmt The stmt to be transformed
* \return Transformed stmt.
*/
Stmt DecorateDeviceScope(Stmt stmt);
* \return a LoweredFunc with the specified signiture.
*
* \note
- * The function signiture have two cases
+ * The function signature have two cases
*
* let num_packed_args = len(api_args) - num_unpacked_args;
*
"double_buffer_split_loop": 1,
"dump_pass_ir": False,
"instrument_bound_checkers": False,
- "disable_select_rewriting": False
+ "disable_select_rewriting": False,
+ "disable_vectorize": False
}
_dump_ir = DumpIR()
# Phase 2
if not simple_mode:
stmt = ir_pass.LoopPartition(stmt, cfg.partition_const_loop)
- stmt = ir_pass.VectorizeLoop(stmt)
+ if cfg.disable_vectorize:
+ stmt = ir_pass.SkipVectorize(stmt)
+ else:
+ stmt = ir_pass.VectorizeLoop(stmt)
stmt = ir_pass.InjectVirtualThread(stmt)
stmt = ir_pass.InjectDoubleBuffer(stmt, cfg.double_buffer_split_loop)
stmt = ir_pass.StorageRewrite(stmt)
if (loop_partition) {
stmt = ir::LoopPartition(stmt, config->partition_const_loop);
}
- stmt = ir::VectorizeLoop(stmt);
+ if (config->disable_vectorize) {
+ stmt = ir::SkipVectorize(stmt);
+ } else {
+ stmt = ir::VectorizeLoop(stmt);
+ }
stmt = ir::InjectVirtualThread(stmt);
stmt = ir::InjectDoubleBuffer(stmt, config->double_buffer_split_loop);
stmt = ir::StorageRewrite(stmt);
p->stream << "dump_pass_ir=" << op->dump_pass_ir << ", ";
p->stream << "instrument_bound_checkers=" << op->instrument_bound_checkers << ", ";
p->stream << "disable_select_rewriting=" << op->disable_select_rewriting;
+ p->stream << "disable_vectorize=" << op->disable_vectorize;
p->stream << ")";
});
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
return LoopVectorizer().Mutate(stmt);
}
+class VectorizeSkipper : public IRMutator {
+ public:
+ Stmt Mutate_(const For* op, const Stmt& s) final {
+ Stmt stmt = IRMutator::Mutate_(op, s);
+ op = stmt.as<For>();
+ if (op->for_type == ForType::Vectorized) {
+ return For::make(op->loop_var, op->min, op->extent, ForType::Serial, op->device_api,
+ op->body);
+ } else {
+ return stmt;
+ }
+ }
+};
+
+Stmt SkipVectorize(Stmt stmt) {
+ return VectorizeSkipper().Mutate(stmt);
+}
+
} // namespace ir
} // namespace tvm