#ifndef MLIR_PASS_PASS_H
#define MLIR_PASS_PASS_H
+#include "mlir/IR/Module.h"
#include "mlir/Pass/PassRegistry.h"
#include "llvm/ADT/PointerIntPair.h"
class Function;
class Module;
-// Values that can be used by to signal success/failure. This can be implicitly
-// converted to/from boolean values, with false representing success and true
-// failure.
-struct LLVM_NODISCARD PassResult {
- enum ResultEnum { Success, Failure } value;
- PassResult(ResultEnum v) : value(v) {}
- operator bool() const { return value == Failure; }
-};
-
/// The abstract base pass class. This class contains information describing the
/// derived pass object, e.g its kind and abstract PassInfo.
class Pass {
/// Returns the unique identifier that corresponds to this pass.
const PassID *getPassID() const { return passIDAndKind.getPointer(); }
- static PassResult success() { return PassResult::Success; }
- static PassResult failure() { return PassResult::Failure; }
-
/// Returns the pass info for the specified pass class or null if unknown.
static const PassInfo *lookupPassInfo(const PassID *passID);
template <typename PassT> static const PassInfo *lookupPassInfo() {
/// The state for a single execution of a pass. This provides a unified
/// interface for accessing and initializing necessary state for pass execution.
template <typename IRUnitT> struct PassExecutionState {
- explicit PassExecutionState(IRUnitT *ir) : ir(ir) {}
+ explicit PassExecutionState(IRUnitT *ir) : irAndPassFailed(ir, false) {}
/// The current IR unit being transformed.
- IRUnitT *ir;
+ llvm::PointerIntPair<IRUnitT *, 1, bool> irAndPassFailed;
};
} // namespace detail
explicit FunctionPassBase(const PassID *id) : Pass(id, Kind::FunctionPass) {}
/// The polymorphic API that runs the pass over the currently held function.
- virtual PassResult runOnFunction() = 0;
+ virtual void runOnFunction() = 0;
/// Return the current function being transformed.
Function &getFunction() {
+ return *getPassState().irAndPassFailed.getPointer();
+ }
+
+ /// Returns the current pass state.
+ detail::PassExecutionState<Function> &getPassState() {
assert(passState && "pass state was never initialized");
- return *passState->ir;
+ return *passState;
}
private:
- /// Forwarding function to execute this pass.
- PassResult run(Function *fn);
+ /// Forwarding function to execute this pass. Returns false if the pass
+ /// execution failed, true otherwise.
+ LLVM_NODISCARD
+ bool run(Function *fn);
/// The current execution state for the pass.
llvm::Optional<detail::PassExecutionState<Function>> passState;
explicit ModulePassBase(const PassID *id) : Pass(id, Kind::ModulePass) {}
/// The polymorphic API that runs the pass over the currently held module.
- virtual PassResult runOnModule() = 0;
+ virtual void runOnModule() = 0;
/// Return the current module being transformed.
- Module &getModule() {
+ Module &getModule() { return *getPassState().irAndPassFailed.getPointer(); }
+
+ /// Returns the current pass state.
+ detail::PassExecutionState<Module> &getPassState() {
assert(passState && "pass state was never initialized");
- return *passState->ir;
+ return *passState;
}
private:
- /// Forwarding function to execute this pass.
- PassResult run(Module *module);
+ /// Forwarding function to execute this pass. Returns false if the pass
+ /// execution failed, true otherwise.
+ LLVM_NODISCARD
+ bool run(Module *module);
/// The current execution state for the pass.
llvm::Optional<detail::PassExecutionState<Module>> passState;
/// TODO(riverriddle) Provide additional utilities for cloning, getting the
/// derived class name, etc..
+
+ /// Signal that some invariant was broken when running. The IR is allowed to
+ /// be in an invalid state.
+ void signalPassFailure() {
+ this->getPassState().irAndPassFailed.setInt(true);
+ }
};
} // end namespace detail
/// additional functions.
///
/// Derived function passes are expected to provide the following:
-/// - A 'PassResult runOnFunction()' method.
+/// - A 'void runOnFunction()' method.
template <typename T>
using FunctionPass = detail::PassModel<Function, T, FunctionPassBase>;
/// A model for providing module pass specific utilities.
///
/// Derived module passes are expected to provide the following:
-/// - A 'PassResult runOnModule()' method.
+/// - A 'void runOnModule()' method.
template <typename T>
using ModulePass = detail::PassModel<Module, T, ModulePassBase>;
} // end namespace mlir
/// executor if necessary.
void addPass(FunctionPassBase *pass);
- /// Run the passes within this manager on the provided module.
+ /// Run the passes within this manager on the provided module. Returns false
+ /// if the run failed, true otherwise.
+ LLVM_NODISCARD
bool run(Module *module);
private:
/// Checks for out of bound memef access subscripts..
struct MemRefBoundCheck : public FunctionPass<MemRefBoundCheck> {
- PassResult runOnFunction() override;
+ void runOnFunction() override;
};
} // end anonymous namespace
return new MemRefBoundCheck();
}
-PassResult MemRefBoundCheck::runOnFunction() {
+void MemRefBoundCheck::runOnFunction() {
getFunction().walk([](Instruction *opInst) {
if (auto loadOp = opInst->dyn_cast<LoadOp>()) {
boundCheckLoadOrStoreOp(loadOp);
}
// TODO(bondhugula): do this for DMA ops as well.
});
- return success();
}
static PassRegistration<MemRefBoundCheck>
/// Checks dependences between all pairs of memref accesses in a Function.
struct MemRefDependenceCheck : public FunctionPass<MemRefDependenceCheck> {
SmallVector<Instruction *, 4> loadsAndStores;
- PassResult runOnFunction() override;
+ void runOnFunction() override;
};
} // end anonymous namespace
// Walks the Function 'f' adding load and store ops to 'loadsAndStores'.
// Runs pair-wise dependence checks.
-PassResult MemRefDependenceCheck::runOnFunction() {
+void MemRefDependenceCheck::runOnFunction() {
// Collect the loads and stores within the function.
loadsAndStores.clear();
getFunction().walk([&](Instruction *inst) {
});
checkDependences(loadsAndStores);
- return success();
}
static PassRegistration<MemRefDependenceCheck>
explicit PrintOpStatsPass(llvm::raw_ostream &os = llvm::errs()) : os(os) {}
// Prints the resultant operation statistics post iterating over the module.
- PassResult runOnModule() override;
+ void runOnModule() override;
// Print summary of op stats.
void printSummary();
};
} // namespace
-PassResult PrintOpStatsPass::runOnModule() {
+void PrintOpStatsPass::runOnModule() {
opCount.clear();
// Compute the operation statistics for each function in the module.
fn.walk(
[&](Instruction *inst) { ++opCount[inst->getName().getStringRef()]; });
printSummary();
- return success();
}
void PrintOpStatsPass::printSummary() {
namespace {
// Testing pass to lower EDSC.
struct LowerEDSCTestPass : public FunctionPass<LowerEDSCTestPass> {
- PassResult runOnFunction() override;
+ void runOnFunction() override;
};
} // end anonymous namespace
#include "mlir/EDSC/reference-impl.inc"
-PassResult LowerEDSCTestPass::runOnFunction() {
+void LowerEDSCTestPass::runOnFunction() {
getFunction().walk([](Instruction *op) {
if (op->getName().getStringRef() == "print") {
auto opName = op->getAttrOfType<StringAttr>("op");
printRefImplementation(opName.getValue(), function.getValue());
}
});
- return success();
}
static PassRegistration<LowerEDSCTestPass> pass("lower-edsc-test",
// Construct and run the default MLIR pipeline.
PassManager manager;
getDefaultPasses(manager, {});
- if (manager.run(m))
+ if (!manager.run(m))
return make_string_error("passes failed");
auto llvmModule = translateModuleToLLVMIR(*m);
/// dialect.
class LLVMLowering : public ModulePass<LLVMLowering>, public DialectConversion {
public:
- PassResult runOnModule() override {
+ void runOnModule() override {
Module *m = &getModule();
uniqueSuccessorsWithArguments(m);
- return DialectConversion::convert(m) ? failure() : success();
+ if (DialectConversion::convert(m))
+ signalPassFailure();
}
protected:
void Pass::anchor() {}
/// Forwarding function to execute this pass.
-PassResult FunctionPassBase::run(Function *fn) {
+bool FunctionPassBase::run(Function *fn) {
/// Initialize the pass state.
passState.emplace(fn);
/// Invoke the virtual runOnFunction function.
- return runOnFunction();
+ runOnFunction();
+
+ // Return false if the pass signaled a failure.
+ return !passState->irAndPassFailed.getInt();
}
-/// Forwarding function to execute this pass.
-PassResult ModulePassBase::run(Module *module) {
+/// Forwarding function to execute this pass. Returns false if the pass
+/// execution failed, true otherwise.
+bool ModulePassBase::run(Module *module) {
/// Initialize the pass state.
passState.emplace(module);
/// Invoke the virtual runOnModule function.
- return runOnModule();
+ runOnModule();
+
+ // Return false if the pass signaled a failure.
+ return !passState->irAndPassFailed.getInt();
}
//===----------------------------------------------------------------------===//
FunctionPassExecutor(const FunctionPassExecutor &) = delete;
FunctionPassExecutor &operator=(const FunctionPassExecutor &) = delete;
- /// Run the executor on the given function.
+ /// Run the executor on the given function. Returns false if the pass
+ /// execution failed, true otherwise.
+ LLVM_NODISCARD
bool run(Function *function);
/// Add a pass to the current executor. This takes ownership over the provided
ModulePassExecutor(const ModulePassExecutor &) = delete;
ModulePassExecutor &operator=(const ModulePassExecutor &) = delete;
- /// Run the executor on the given module.
+ /// Run the executor on the given module. Returns false if the pass
+ /// execution failed, true otherwise.
+ LLVM_NODISCARD
bool run(Module *module);
/// Add a pass to the current executor. This takes ownership over the provided
bool detail::FunctionPassExecutor::run(Function *function) {
for (auto &pass : passes) {
/// Create an execution state for this pass.
- if (pass->run(function))
- return true;
+ if (!pass->run(function))
+ return false;
// TODO: This should be opt-out and handled separately.
if (function->verify())
- return true;
+ return false;
}
- return false;
+ return true;
}
/// Run all of the passes in this manager over the current module.
bool detail::ModulePassExecutor::run(Module *module) {
for (auto &pass : passes) {
- if (pass->run(module))
- return true;
+ if (!pass->run(module))
+ return false;
// TODO: This should be opt-out and handled separately.
if (module->verify())
- return true;
+ return false;
}
- return false;
+ return true;
}
//===----------------------------------------------------------------------===//
ModuleToFunctionPassAdaptor &
operator=(const ModuleToFunctionPassAdaptor &) = delete;
- /// run the held function pipeline over all non-external functions within the
+ /// Run the held function pipeline over all non-external functions within the
/// module.
- PassResult runOnModule() override;
+ void runOnModule() override;
/// Returns the function pass executor for this adaptor.
FunctionPassExecutor &getFunctionExecutor() { return fpe; }
/// Execute the held function pass over all non-external functions within the
/// module.
-PassResult ModuleToFunctionPassAdaptor::runOnModule() {
+void ModuleToFunctionPassAdaptor::runOnModule() {
for (auto &func : getModule()) {
// Skip external functions.
if (func.isExternal())
continue;
// Run the held function pipeline over the current function.
- if (fpe.run(&func))
- return failure();
+ if (!fpe.run(&func))
+ return signalPassFailure();
}
- return success();
}
//===----------------------------------------------------------------------===//
void simplifyBlock(DominanceInfo &domInfo, Block *bb);
void simplifyBlockList(DominanceInfo &domInfo, BlockList &blockList);
- PassResult runOnFunction() override;
+ void runOnFunction() override;
private:
/// A scoped hash table of defining operations within a function.
}
}
-PassResult CSE::runOnFunction() {
+void CSE::runOnFunction() {
DominanceInfo domInfo(&getFunction());
simplifyBlockList(domInfo, getFunction().getBlockList());
for (auto *op : opsToErase)
op->erase();
opsToErase.clear();
-
- return success();
}
FunctionPassBase *mlir::createCSEPass() { return new CSE(); }
/// Canonicalize operations in functions.
struct Canonicalizer : public FunctionPass<Canonicalizer> {
- PassResult runOnFunction() override;
+ void runOnFunction() override;
};
} // end anonymous namespace
-PassResult Canonicalizer::runOnFunction() {
+void Canonicalizer::runOnFunction() {
OwningRewritePatternList patterns;
auto &func = getFunction();
op->getCanonicalizationPatterns(patterns, context);
applyPatternsGreedily(&func, std::move(patterns));
- return success();
}
/// Create a Canonicalizer pass.
std::vector<Instruction *> opInstsToErase;
void foldInstruction(Instruction *op);
- PassResult runOnFunction() override;
+ void runOnFunction() override;
};
} // end anonymous namespace
// For now, we do a simple top-down pass over a function folding constants. We
// don't handle conditional control flow, block arguments, folding
// conditional branches, or anything else fancy.
-PassResult ConstantFold::runOnFunction() {
+void ConstantFold::runOnFunction() {
existingConstants.clear();
opInstsToErase.clear();
if (cst->use_empty())
cst->getDefiningInst()->erase();
}
-
- return success();
}
/// Creates a constant folding pass.
minDmaTransferSize(minDmaTransferSize),
fastMemCapacityBytes(fastMemCapacityBytes) {}
- PassResult runOnFunction() override;
+ void runOnFunction() override;
bool runOnBlock(Block *block);
uint64_t runOnBlock(Block::iterator begin, Block::iterator end);
return totalDmaBuffersSizeInBytes;
}
-PassResult DmaGeneration::runOnFunction() {
+void DmaGeneration::runOnFunction() {
Function *f = &getFunction();
FuncBuilder topBuilder(f);
zeroIndex = topBuilder.create<ConstantIndexOp>(f->getLoc(), 0);
- for (auto &block : *f) {
+ for (auto &block : *f)
runOnBlock(&block);
- }
- // This function never leaves the IR in an invalid state.
- return success();
}
static PassRegistration<DmaGeneration>
: localBufSizeThreshold(localBufSizeThreshold),
fastMemorySpace(fastMemorySpace) {}
- PassResult runOnFunction() override;
+ void runOnFunction() override;
// Any local buffers smaller than this size (in bytes) will be created in
// `fastMemorySpace` if provided.
} // end anonymous namespace
-PassResult LoopFusion::runOnFunction() {
+void LoopFusion::runOnFunction() {
// Override if a command line argument was provided.
if (clFusionFastMemorySpace.getNumOccurrences() > 0) {
fastMemorySpace = clFusionFastMemorySpace.getValue();
MemRefDependenceGraph g;
if (g.init(&getFunction()))
GreedyFusion(&g).run(localBufSizeThreshold, fastMemorySpace);
- return success();
}
static PassRegistration<LoopFusion> pass("loop-fusion", "Fuse loop nests");
/// A pass to perform loop tiling on all suitable loop nests of a Function.
struct LoopTiling : public FunctionPass<LoopTiling> {
- PassResult runOnFunction() override;
+ void runOnFunction() override;
constexpr static unsigned kDefaultTileSize = 4;
};
getMaximalPerfectLoopNest(forOp);
}
-PassResult LoopTiling::runOnFunction() {
+void LoopTiling::runOnFunction() {
std::vector<SmallVector<OpPointer<AffineForOp>, 6>> bands;
getTileableBands(&getFunction(), &bands);
clTileSizes.begin() + std::min(clTileSizes.size(), band.size()),
tileSizes.begin());
- if (tileCodeGen(band, tileSizes)) {
- return failure();
- }
+ if (tileCodeGen(band, tileSizes))
+ return signalPassFailure();
}
- return success();
}
static PassRegistration<LoopTiling> pass("loop-tile", "Tile loop nests");
: unrollFactor(unrollFactor), unrollFull(unrollFull),
getUnrollFactor(getUnrollFactor) {}
- PassResult runOnFunction() override;
+ void runOnFunction() override;
/// Unroll this for inst. Returns false if nothing was done.
bool runOnAffineForOp(OpPointer<AffineForOp> forOp);
};
} // end anonymous namespace
-PassResult LoopUnroll::runOnFunction() {
+void LoopUnroll::runOnFunction() {
// Gathers all innermost loops through a post order pruned walk.
struct InnermostLoopGatherer {
// Store innermost loops as we walk.
});
for (auto forOp : loops)
loopUnrollFull(forOp);
- return success();
+ return;
}
unsigned numRepetitions = clUnrollNumRepetitions.getNumOccurrences() > 0
// Break out if nothing was unrolled.
break;
}
- return success();
}
/// Unrolls a 'for' inst. Returns true if the loop was unrolled, false
explicit LoopUnrollAndJam(Optional<unsigned> unrollJamFactor = None)
: unrollJamFactor(unrollJamFactor) {}
- PassResult runOnFunction() override;
+ void runOnFunction() override;
bool runOnAffineForOp(OpPointer<AffineForOp> forOp);
};
} // end anonymous namespace
unrollJamFactor == -1 ? None : Optional<unsigned>(unrollJamFactor));
}
-PassResult LoopUnrollAndJam::runOnFunction() {
+void LoopUnrollAndJam::runOnFunction() {
// Currently, just the outermost loop from the first loop nest is
// unroll-and-jammed by this pass. However, runOnAffineForOp can be called on
// any for operation.
auto &entryBlock = getFunction().front();
if (auto forOp = entryBlock.front().dyn_cast<AffineForOp>())
runOnAffineForOp(forOp);
-
- return success();
}
/// Unroll and jam a 'for' inst. Default unroll jam factor is
namespace {
struct LowerAffinePass : public FunctionPass<LowerAffinePass> {
- PassResult runOnFunction() override;
+ void runOnFunction() override;
bool lowerAffineFor(OpPointer<AffineForOp> forOp);
bool lowerAffineIf(AffineIfOp *ifOp);
// construction. When an Value is used, it gets replaced with the
// corresponding Value that has been defined previously. The value flow
// starts with function arguments converted to basic block arguments.
-PassResult LowerAffinePass::runOnFunction() {
+void LowerAffinePass::runOnFunction() {
SmallVector<Instruction *, 8> instsToRewrite;
// Collect all the For instructions as well as AffineIfOps and AffineApplyOps.
for (auto *inst : instsToRewrite) {
if (auto ifOp = inst->dyn_cast<AffineIfOp>()) {
if (lowerAffineIf(ifOp))
- return failure();
+ return signalPassFailure();
} else if (auto forOp = inst->dyn_cast<AffineForOp>()) {
if (lowerAffineFor(forOp))
- return failure();
+ return signalPassFailure();
} else if (lowerAffineApply(inst->cast<AffineApplyOp>())) {
- return failure();
+ return signalPassFailure();
}
}
-
- return success();
}
/// Lowers If and For instructions within a function into their lower level CFG
struct LowerVectorTransfersPass
: public FunctionPass<LowerVectorTransfersPass> {
- PassResult runOnFunction() {
+ void runOnFunction() {
Function *f = &getFunction();
applyMLPatternsGreedily<VectorTransferExpander<VectorTransferReadOp>,
VectorTransferExpander<VectorTransferWriteOp>>(f);
- return success();
}
// Thread-safe RAII context with local scope. BumpPtrAllocator freed on exit.
};
struct MaterializeVectorsPass : public FunctionPass<MaterializeVectorsPass> {
- PassResult runOnFunction() override;
+ void runOnFunction() override;
};
} // end anonymous namespace
return false;
}
-PassResult MaterializeVectorsPass::runOnFunction() {
+void MaterializeVectorsPass::runOnFunction() {
// Thread-safe RAII local context, BumpPtrAllocator freed on exit.
NestedPatternContext mlContext;
// TODO(ntv): Check to see if this supports arbitrary top-level code.
Function *f = &getFunction();
if (f->getBlocks().size() != 1)
- return success();
+ return;
using matcher::Op;
LLVM_DEBUG(dbgs() << "\nMaterializeVectors on Function\n");
terminators.insert(m.getMatchedInstruction());
}
- auto fail = materialize(f, terminators, &state);
- return fail ? PassResult::Failure : PassResult::Success;
+ if (materialize(f, terminators, &state))
+ signalPassFailure();
}
FunctionPassBase *mlir::createMaterializeVectorsPass() {
// than dealloc) remain.
//
struct MemRefDataFlowOpt : public FunctionPass<MemRefDataFlowOpt> {
- PassResult runOnFunction() override;
+ void runOnFunction() override;
void forwardStoreToLoad(OpPointer<LoadOp> loadOp);
loadOpsToErase.push_back(loadOpInst);
}
-PassResult MemRefDataFlowOpt::runOnFunction() {
+void MemRefDataFlowOpt::runOnFunction() {
// Only supports single block functions at the moment.
Function &f = getFunction();
if (f.getBlocks().size() != 1)
- return success();
+ return;
DominanceInfo theDomInfo(&f);
domInfo = &theDomInfo;
use.getOwner()->erase();
defInst->erase();
}
-
- // This function never leaves the IR in an invalid state.
- return success();
}
static PassRegistration<MemRefDataFlowOpt>
namespace {
struct PipelineDataTransfer : public FunctionPass<PipelineDataTransfer> {
- PassResult runOnFunction() override;
- PassResult runOnAffineForOp(OpPointer<AffineForOp> forOp);
+ void runOnFunction() override;
+ void runOnAffineForOp(OpPointer<AffineForOp> forOp);
std::vector<OpPointer<AffineForOp>> forOps;
};
}
/// Returns success if the IR is in a valid state.
-PassResult PipelineDataTransfer::runOnFunction() {
+void PipelineDataTransfer::runOnFunction() {
// Do a post order walk so that inner loop DMAs are processed first. This is
// necessary since 'for' instructions nested within would otherwise become
// invalid (erased) when the outer loop is pipelined (the pipelined one gets
forOps.clear();
getFunction().walkPostOrder<AffineForOp>(
[&](OpPointer<AffineForOp> forOp) { forOps.push_back(forOp); });
- bool ret = false;
- for (auto forOp : forOps) {
- ret = ret | runOnAffineForOp(forOp);
- }
- return ret ? failure() : success();
+ for (auto forOp : forOps)
+ runOnAffineForOp(forOp);
}
// Check if tags of the dma start op and dma wait op match.
/// Overlap DMA transfers with computation in this loop. If successful,
/// 'forOp' is deleted, and a prologue, a new pipelined loop, and epilogue are
/// inserted right before where it was.
-PassResult
-PipelineDataTransfer::runOnAffineForOp(OpPointer<AffineForOp> forOp) {
+void PipelineDataTransfer::runOnAffineForOp(OpPointer<AffineForOp> forOp) {
auto mayBeConstTripCount = getConstantTripCount(forOp);
if (!mayBeConstTripCount.hasValue()) {
LLVM_DEBUG(
forOp->emitNote("won't pipeline due to unknown trip count loop"));
- return success();
+ return;
}
SmallVector<std::pair<Instruction *, Instruction *>, 4> startWaitPairs;
if (startWaitPairs.empty()) {
LLVM_DEBUG(forOp->emitNote("No dma start/finish pairs\n"));
- return success();
+ return;
}
// Double the buffers for the higher memory space memref's.
LLVM_DEBUG(llvm::dbgs() << "double buffering failed for: \n";);
LLVM_DEBUG(dmaStartInst->dump());
// IR still in a valid state.
- return success();
+ return;
}
// If the old memref has no more uses, remove its 'dead' alloc if it was
// alloc'ed. (note: DMA buffers are rarely function live-in; but a 'dim'
dmaFinishInst->getOperand(getTagMemRefPos(*dmaFinishInst));
if (!doubleBuffer(oldTagMemRef, forOp)) {
LLVM_DEBUG(llvm::dbgs() << "tag double buffering failed\n";);
- return success();
+ return;
}
// If the old tag has no more uses, remove its 'dead' alloc if it was
// alloc'ed.
if (!isInstwiseShiftValid(forOp, shifts)) {
// Violates dependences.
LLVM_DEBUG(llvm::dbgs() << "Shifts invalid - unexpected\n";);
- return success();
+ return;
}
if (instBodySkew(forOp, shifts)) {
LLVM_DEBUG(llvm::dbgs() << "inst body skewing failed - unexpected\n";);
- return success();
+ return;
}
-
- return success();
}
static PassRegistration<PipelineDataTransfer> pass(
/// on AffineMap and driven from the existing canonicalization pass.
struct SimplifyAffineStructures
: public FunctionPass<SimplifyAffineStructures> {
- PassResult runOnFunction() override;
+ void runOnFunction() override;
};
} // end anonymous namespace
return set;
}
-PassResult SimplifyAffineStructures::runOnFunction() {
+void SimplifyAffineStructures::runOnFunction() {
getFunction().walk([&](Instruction *opInst) {
for (auto attr : opInst->getAttrs()) {
if (auto mapAttr = attr.second.dyn_cast<AffineMapAttr>()) {
}
}
});
-
- return success();
}
static PassRegistration<SimplifyAffineStructures>
namespace {
struct StripDebugInfo : public FunctionPass<StripDebugInfo> {
- PassResult runOnFunction() override;
+ void runOnFunction() override;
};
} // end anonymous namespace
-PassResult StripDebugInfo::runOnFunction() {
+void StripDebugInfo::runOnFunction() {
Function &func = getFunction();
UnknownLoc unknownLoc = UnknownLoc::get(func.getContext());
// Strip the debug info from the function and its instructions.
func.setLoc(unknownLoc);
func.walk([&](Instruction *inst) { inst->setLoc(unknownLoc); });
- return success();
}
/// Creates a pass to strip debug information from a function.
static constexpr auto kTestAffineMapOpName = "test_affine_map";
static constexpr auto kTestAffineMapAttrName = "affine_map";
- PassResult runOnFunction() override;
+ void runOnFunction() override;
void testVectorShapeRatio(Function *f);
void testForwardSlicing(Function *f);
void testBackwardSlicing(Function *f);
}
}
-PassResult VectorizerTestPass::runOnFunction() {
+void VectorizerTestPass::runOnFunction() {
// Thread-safe RAII local context, BumpPtrAllocator freed on exit.
NestedPatternContext mlContext;
// Only support single block functions at this point.
Function *f = &getFunction();
if (f->getBlocks().size() != 1)
- return success();
+ return;
if (!clTestVectorShapeRatio.empty()) {
testVectorShapeRatio(f);
if (clTestNormalizeMaps) {
testNormalizeMaps(f);
}
- return PassResult::Success;
}
FunctionPassBase *mlir::createVectorizerTestPass() {
namespace {
struct Vectorize : public FunctionPass<Vectorize> {
- PassResult runOnFunction() override;
+ void runOnFunction() override;
};
} // end anonymous namespace
/// Applies vectorization to the current Function by searching over a bunch of
/// predetermined patterns.
-PassResult Vectorize::runOnFunction() {
+void Vectorize::runOnFunction() {
// Thread-safe RAII local context, BumpPtrAllocator freed on exit.
NestedPatternContext mlContext;
}
}
LLVM_DEBUG(dbgs() << "\n");
- return PassResult::Success;
}
FunctionPassBase *mlir::createVectorizePass() { return new Vectorize(); }
PrintCFGPass(llvm::raw_ostream &os = llvm::errs(), bool shortNames = false,
const llvm::Twine &title = "")
: os(os), shortNames(shortNames), title(title) {}
- PassResult runOnFunction() {
+ void runOnFunction() {
mlir::writeGraph(os, &getFunction(), shortNames, title);
- return success();
}
private:
PassManager pm;
for (const auto *passEntry : *passList)
passEntry->addToPipeline(pm);
- if (pm.run(module.get()))
+ if (!pm.run(module.get()))
return OptFailure;
std::string errorMessage;