Skip to content

Commit e21adfa

Browse files
committed
[mlir] Mark LogicalResult as LLVM_NODISCARD
This makes ignoring a result explicit by the user, and helps to prevent accidental errors with dropped results. Marking LogicalResult as no discard was always the intention from the beginning, but got lost along the way. Differential Revision: https://reviews.llvm.org/D95841
1 parent e355110 commit e21adfa

File tree

77 files changed

+352
-310
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+352
-310
lines changed

mlir/include/mlir/IR/OpDefinition.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class ParseResult : public LogicalResult {
4141
ParseResult(const Diagnostic &) : LogicalResult(failure()) {}
4242

4343
/// Failure is true in a boolean context.
44-
explicit operator bool() const { return failed(*this); }
44+
explicit operator bool() const { return failed(); }
4545
};
4646
/// This class implements `Optional` functionality for ParseResult. We don't
4747
/// directly use Optional here, because it provides an implicit conversion

mlir/include/mlir/IR/SymbolTable.h

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -189,17 +189,17 @@ class SymbolTable {
189189
/// 'from'. This does not traverse into any nested symbol tables. If there are
190190
/// any unknown operations that may potentially be symbol tables, no uses are
191191
/// replaced and failure is returned.
192-
LLVM_NODISCARD static LogicalResult replaceAllSymbolUses(StringRef oldSymbol,
193-
StringRef newSymbol,
194-
Operation *from);
195-
LLVM_NODISCARD static LogicalResult
196-
replaceAllSymbolUses(Operation *oldSymbol, StringRef newSymbolName,
197-
Operation *from);
198-
LLVM_NODISCARD static LogicalResult
199-
replaceAllSymbolUses(StringRef oldSymbol, StringRef newSymbol, Region *from);
200-
LLVM_NODISCARD static LogicalResult
201-
replaceAllSymbolUses(Operation *oldSymbol, StringRef newSymbolName,
202-
Region *from);
192+
static LogicalResult replaceAllSymbolUses(StringRef oldSymbol,
193+
StringRef newSymbol,
194+
Operation *from);
195+
static LogicalResult replaceAllSymbolUses(Operation *oldSymbol,
196+
StringRef newSymbolName,
197+
Operation *from);
198+
static LogicalResult replaceAllSymbolUses(StringRef oldSymbol,
199+
StringRef newSymbol, Region *from);
200+
static LogicalResult replaceAllSymbolUses(Operation *oldSymbol,
201+
StringRef newSymbolName,
202+
Region *from);
203203

204204
private:
205205
Operation *symbolTableOp;

mlir/include/mlir/Pass/PassManager.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,6 @@ class PassManager : public OpPassManager {
178178
/// Run the passes within this manager on the provided operation. The
179179
/// specified operation must have the same name as the one provided the pass
180180
/// manager on construction.
181-
LLVM_NODISCARD
182181
LogicalResult run(Operation *op);
183182

184183
/// Return an instance of the context.

mlir/include/mlir/Support/LogicalResult.h

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,38 +14,62 @@
1414

1515
namespace mlir {
1616

17-
/// Values that can be used to signal success/failure. This should be used in
18-
/// conjunction with the utility functions below.
19-
struct LogicalResult {
20-
enum ResultEnum { Success, Failure } value;
21-
LogicalResult(ResultEnum v) : value(v) {}
17+
/// This class represents an efficient way to signal success or failure. It
18+
/// should be preferred over the use of `bool` when appropriate, as it avoids
19+
/// all of the ambiguity that arises in interpreting a boolean result. This
20+
/// class is marked as NODISCARD to ensure that the result is processed. Users
21+
/// may explicitly discard a result by using `(void)`, e.g.
22+
/// `(void)functionThatReturnsALogicalResult();`. Given the intended nature of
23+
/// this class, it generally shouldn't be used as the result of functions that
24+
/// very frequently have the result ignored. This class is intended to be used
25+
/// in conjunction with the utility functions below.
26+
struct LLVM_NODISCARD LogicalResult {
27+
public:
28+
/// If isSuccess is true a `success` result is generated, otherwise a
29+
/// 'failure' result is generated.
30+
static LogicalResult success(bool isSuccess = true) {
31+
return LogicalResult(isSuccess);
32+
}
33+
34+
/// If isFailure is true a `failure` result is generated, otherwise a
35+
/// 'success' result is generated.
36+
static LogicalResult failure(bool isFailure = true) {
37+
return success(!isFailure);
38+
}
39+
40+
/// Returns true if the provided LogicalResult corresponds to a success value.
41+
bool succeeded() const { return isSuccess; }
42+
43+
/// Returns true if the provided LogicalResult corresponds to a failure value.
44+
bool failed() const { return !succeeded(); }
45+
46+
private:
47+
LogicalResult(bool isSuccess) : isSuccess(isSuccess) {}
48+
49+
/// Boolean indicating if this is a success result, if false this is a
50+
/// failure result.
51+
bool isSuccess;
2252
};
2353

2454
/// Utility function to generate a LogicalResult. If isSuccess is true a
2555
/// `success` result is generated, otherwise a 'failure' result is generated.
2656
inline LogicalResult success(bool isSuccess = true) {
27-
return LogicalResult{isSuccess ? LogicalResult::Success
28-
: LogicalResult::Failure};
57+
return LogicalResult::success(isSuccess);
2958
}
3059

3160
/// Utility function to generate a LogicalResult. If isFailure is true a
3261
/// `failure` result is generated, otherwise a 'success' result is generated.
3362
inline LogicalResult failure(bool isFailure = true) {
34-
return LogicalResult{isFailure ? LogicalResult::Failure
35-
: LogicalResult::Success};
63+
return LogicalResult::failure(isFailure);
3664
}
3765

3866
/// Utility function that returns true if the provided LogicalResult corresponds
3967
/// to a success value.
40-
inline bool succeeded(LogicalResult result) {
41-
return result.value == LogicalResult::Success;
42-
}
68+
inline bool succeeded(LogicalResult result) { return result.succeeded(); }
4369

4470
/// Utility function that returns true if the provided LogicalResult corresponds
4571
/// to a failure value.
46-
inline bool failed(LogicalResult result) {
47-
return result.value == LogicalResult::Failure;
48-
}
72+
inline bool failed(LogicalResult result) { return result.failed(); }
4973

5074
/// This class provides support for representing a failure result, or a valid
5175
/// value of type `T`. This allows for integrating with LogicalResult, while

mlir/include/mlir/Transforms/DialectConversion.h

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -829,11 +829,11 @@ class ConversionTarget {
829829
/// legalizable to the given `target` are placed within that set. (Note that if
830830
/// there is an op explicitly marked as illegal, the conversion terminates and
831831
/// the `unconvertedOps` set will not necessarily be complete.)
832-
LLVM_NODISCARD LogicalResult
832+
LogicalResult
833833
applyPartialConversion(ArrayRef<Operation *> ops, ConversionTarget &target,
834834
const FrozenRewritePatternList &patterns,
835835
DenseSet<Operation *> *unconvertedOps = nullptr);
836-
LLVM_NODISCARD LogicalResult
836+
LogicalResult
837837
applyPartialConversion(Operation *op, ConversionTarget &target,
838838
const FrozenRewritePatternList &patterns,
839839
DenseSet<Operation *> *unconvertedOps = nullptr);
@@ -842,12 +842,11 @@ applyPartialConversion(Operation *op, ConversionTarget &target,
842842
/// operations. This method returns failure if the conversion of any operation
843843
/// fails, or if there are unreachable blocks in any of the regions nested
844844
/// within 'ops'.
845-
LLVM_NODISCARD LogicalResult
846-
applyFullConversion(ArrayRef<Operation *> ops, ConversionTarget &target,
847-
const FrozenRewritePatternList &patterns);
848-
LLVM_NODISCARD LogicalResult
849-
applyFullConversion(Operation *op, ConversionTarget &target,
850-
const FrozenRewritePatternList &patterns);
845+
LogicalResult applyFullConversion(ArrayRef<Operation *> ops,
846+
ConversionTarget &target,
847+
const FrozenRewritePatternList &patterns);
848+
LogicalResult applyFullConversion(Operation *op, ConversionTarget &target,
849+
const FrozenRewritePatternList &patterns);
851850

852851
/// Apply an analysis conversion on the given operations, and all nested
853852
/// operations. This method analyzes which operations would be successfully
@@ -857,14 +856,13 @@ applyFullConversion(Operation *op, ConversionTarget &target,
857856
/// operations on success and only pre-existing operations are added to the set.
858857
/// This method only returns failure if there are unreachable blocks in any of
859858
/// the regions nested within 'ops'.
860-
LLVM_NODISCARD LogicalResult
861-
applyAnalysisConversion(ArrayRef<Operation *> ops, ConversionTarget &target,
862-
const FrozenRewritePatternList &patterns,
863-
DenseSet<Operation *> &convertedOps);
864-
LLVM_NODISCARD LogicalResult
865-
applyAnalysisConversion(Operation *op, ConversionTarget &target,
866-
const FrozenRewritePatternList &patterns,
867-
DenseSet<Operation *> &convertedOps);
859+
LogicalResult applyAnalysisConversion(ArrayRef<Operation *> ops,
860+
ConversionTarget &target,
861+
const FrozenRewritePatternList &patterns,
862+
DenseSet<Operation *> &convertedOps);
863+
LogicalResult applyAnalysisConversion(Operation *op, ConversionTarget &target,
864+
const FrozenRewritePatternList &patterns,
865+
DenseSet<Operation *> &convertedOps);
868866
} // end namespace mlir
869867

870868
#endif // MLIR_TRANSFORMS_DIALECTCONVERSION_H_

mlir/include/mlir/Transforms/LoopUtils.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ void promoteSingleIterationLoops(FuncOp f);
8585
/// order, and are multiplied by the loop 'step' before being applied. If
8686
/// `unrollPrologueEpilogue` is set, fully unroll the prologue and epilogue
8787
/// loops when possible.
88-
LLVM_NODISCARD
8988
LogicalResult affineForOpBodySkew(AffineForOp forOp, ArrayRef<uint64_t> shifts,
9089
bool unrollPrologueEpilogue = false);
9190

@@ -97,7 +96,6 @@ void getTileableBands(FuncOp f,
9796

9897
/// Tiles the specified band of perfectly nested loops creating tile-space loops
9998
/// and intra-tile loops. A band is a contiguous set of loops.
100-
LLVM_NODISCARD
10199
LogicalResult
102100
tilePerfectlyNested(MutableArrayRef<AffineForOp> input,
103101
ArrayRef<unsigned> tileSizes,
@@ -106,7 +104,6 @@ tilePerfectlyNested(MutableArrayRef<AffineForOp> input,
106104
/// Tiles the specified band of perfectly nested loops creating tile-space
107105
/// loops and intra-tile loops, using SSA values as tiling parameters. A band
108106
/// is a contiguous set of loops.
109-
LLVM_NODISCARD
110107
LogicalResult tilePerfectlyNestedParametric(
111108
MutableArrayRef<AffineForOp> input, ArrayRef<Value> tileSizes,
112109
SmallVectorImpl<AffineForOp> *tiledNest = nullptr);

mlir/lib/Analysis/Presburger/Simplex.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ LogicalResult Simplex::restoreRow(Unknown &u) {
272272

273273
pivot(*maybePivot);
274274
if (u.orientation == Orientation::Column)
275-
return LogicalResult::Success; // the unknown is unbounded above.
275+
return success(); // the unknown is unbounded above.
276276
}
277277
return success(tableau(u.pos, 1) >= 0);
278278
}
@@ -509,7 +509,7 @@ Optional<Fraction> Simplex::computeOptimum(Direction direction, Unknown &u) {
509509
Optional<Fraction> optimum = computeRowOptimum(direction, row);
510510
if (u.restricted && direction == Direction::Down &&
511511
(!optimum || *optimum < Fraction(0, 1)))
512-
restoreRow(u);
512+
(void)restoreRow(u);
513513
return optimum;
514514
}
515515

@@ -572,7 +572,7 @@ void Simplex::detectRedundant() {
572572
if (!minimum || *minimum < Fraction(0, 1)) {
573573
// Constraint is unbounded below or can attain negative sample values and
574574
// hence is not redundant.
575-
restoreRow(u);
575+
(void)restoreRow(u);
576576
continue;
577577
}
578578

mlir/lib/Conversion/AffineToStandard/AffineToStandard.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,8 @@ static Value getIdentityValue(AtomicRMWKind op, OpBuilder &builder,
379379
return builder.create<ConstantOp>(loc, builder.getI32IntegerAttr(1));
380380
// TODO: Add remaining reduction operations.
381381
default:
382-
emitOptionalError(loc, "Reduction operation type not supported");
382+
(void)emitOptionalError(loc, "Reduction operation type not supported");
383+
break;
383384
}
384385
return nullptr;
385386
}
@@ -399,7 +400,8 @@ static Value getReductionOp(AtomicRMWKind op, OpBuilder &builder, Location loc,
399400
return builder.create<MulIOp>(loc, lhs, rhs);
400401
// TODO: Add remaining reduction operations.
401402
default:
402-
emitOptionalError(loc, "Reduction operation type not supported");
403+
(void)emitOptionalError(loc, "Reduction operation type not supported");
404+
break;
403405
}
404406
return nullptr;
405407
}

mlir/lib/Conversion/GPUToNVVM/LowerGpuOpsToNVVMOps.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ struct LowerGpuOpsToNVVMOpsPass
128128
// which need to be lowered further, which is not supported by a single
129129
// conversion pass.
130130
populateGpuRewritePatterns(m.getContext(), patterns);
131-
applyPatternsAndFoldGreedily(m, std::move(patterns));
131+
(void)applyPatternsAndFoldGreedily(m, std::move(patterns));
132132

133133
populateStdToLLVMConversionPatterns(converter, llvmPatterns);
134134
populateGpuToNVVMConversionPatterns(converter, llvmPatterns);

mlir/lib/Conversion/GPUToROCDL/LowerGpuOpsToROCDLOps.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ struct LowerGpuOpsToROCDLOpsPass
6262
OwningRewritePatternList patterns, llvmPatterns;
6363

6464
populateGpuRewritePatterns(m.getContext(), patterns);
65-
applyPatternsAndFoldGreedily(m, std::move(patterns));
65+
(void)applyPatternsAndFoldGreedily(m, std::move(patterns));
6666

6767
populateVectorToLLVMConversionPatterns(converter, llvmPatterns);
6868
populateVectorToROCDLConversionPatterns(converter, llvmPatterns);

mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRV.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,8 @@ lowerAsEntryFunction(gpu::GPUFuncOp funcOp, TypeConverter &typeConverter,
208208
return nullptr;
209209
rewriter.eraseOp(funcOp);
210210

211-
spirv::setABIAttrs(newFuncOp, entryPointInfo, argABIInfo);
211+
if (failed(spirv::setABIAttrs(newFuncOp, entryPointInfo, argABIInfo)))
212+
return nullptr;
212213
return newFuncOp;
213214
}
214215

mlir/lib/Conversion/SPIRVToLLVM/ConvertLaunchFuncToLLVMCalls.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ class LowerHostCodeToLLVM
295295
// Finally, modify the kernel function in SPIR-V modules to avoid symbolic
296296
// conflicts.
297297
for (auto spvModule : module.getOps<spirv::ModuleOp>())
298-
encodeKernelName(spvModule);
298+
(void)encodeKernelName(spvModule);
299299
}
300300
};
301301
} // namespace

mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -888,9 +888,9 @@ class LoadStorePattern : public SPIRVToLLVMConversion<SPIRVop> {
888888
ConversionPatternRewriter &rewriter) const override {
889889

890890
if (!op.memory_access().hasValue()) {
891-
replaceWithLoadOrStore(op, rewriter, this->typeConverter, /*alignment=*/0,
892-
/*isVolatile=*/false, /*isNonTemporal=*/false);
893-
return success();
891+
return replaceWithLoadOrStore(
892+
op, rewriter, this->typeConverter, /*alignment=*/0,
893+
/*isVolatile=*/false, /*isNonTemporal=*/false);
894894
}
895895
auto memoryAccess = op.memory_access().getValue();
896896
switch (memoryAccess) {
@@ -902,9 +902,8 @@ class LoadStorePattern : public SPIRVToLLVMConversion<SPIRVop> {
902902
memoryAccess == spirv::MemoryAccess::Aligned ? *op.alignment() : 0;
903903
bool isNonTemporal = memoryAccess == spirv::MemoryAccess::Nontemporal;
904904
bool isVolatile = memoryAccess == spirv::MemoryAccess::Volatile;
905-
replaceWithLoadOrStore(op, rewriter, this->typeConverter, alignment,
906-
isVolatile, isNonTemporal);
907-
return success();
905+
return replaceWithLoadOrStore(op, rewriter, this->typeConverter,
906+
alignment, isVolatile, isNonTemporal);
908907
}
909908
default:
910909
// There is no support of other memory access attributes.

mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3111,9 +3111,10 @@ struct ReturnOpLowering : public ConvertOpToLLVMPattern<ReturnOp> {
31113111
}
31123112
} else {
31133113
updatedOperands = llvm::to_vector<4>(operands);
3114-
copyUnrankedDescriptors(rewriter, loc, *getTypeConverter(),
3115-
op.getOperands().getTypes(), updatedOperands,
3116-
/*toDynamic=*/true);
3114+
(void)copyUnrankedDescriptors(rewriter, loc, *getTypeConverter(),
3115+
op.getOperands().getTypes(),
3116+
updatedOperands,
3117+
/*toDynamic=*/true);
31173118
}
31183119

31193120
// If ReturnOp has 0 or 1 operand, create it and return immediately.

mlir/lib/Conversion/StandardToSPIRV/LegalizeStandardForSPIRV.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,8 @@ void SPIRVLegalization::runOnOperation() {
214214
OwningRewritePatternList patterns;
215215
auto *context = &getContext();
216216
populateStdLegalizationPatternsForSPIRVLowering(context, patterns);
217-
applyPatternsAndFoldGreedily(getOperation()->getRegions(),
218-
std::move(patterns));
217+
(void)applyPatternsAndFoldGreedily(getOperation()->getRegions(),
218+
std::move(patterns));
219219
}
220220

221221
std::unique_ptr<Pass> mlir::createLegalizeStdOpsForSPIRVLoweringPass() {

mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ createLinalgBodyCalculationForElementwiseOp(Operation *op, ValueRange args,
137137
if (isa<tosa::FloorOp>(op) && elementTy.isa<FloatType>())
138138
return rewriter.create<mlir::FloorFOp>(loc, resultTypes, args);
139139

140-
rewriter.notifyMatchFailure(
140+
(void)rewriter.notifyMatchFailure(
141141
op, "unhandled op for linalg body calculation for elementwise op");
142142
return nullptr;
143143
}

mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVMPass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ void LowerVectorToLLVMPass::runOnOperation() {
6161
populateVectorToVectorCanonicalizationPatterns(patterns, &getContext());
6262
populateVectorSlicesLoweringPatterns(patterns, &getContext());
6363
populateVectorContractLoweringPatterns(patterns, &getContext());
64-
applyPatternsAndFoldGreedily(getOperation(), std::move(patterns));
64+
(void)applyPatternsAndFoldGreedily(getOperation(), std::move(patterns));
6565
}
6666

6767
// Convert to the LLVM IR dialect.

mlir/lib/Conversion/VectorToSCF/VectorToSCF.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,7 @@ struct ConvertVectorToSCFPass
713713
auto *context = getFunction().getContext();
714714
populateVectorToSCFConversionPatterns(
715715
patterns, context, VectorTransferToSCFOptions().setUnroll(fullUnroll));
716-
applyPatternsAndFoldGreedily(getFunction(), std::move(patterns));
716+
(void)applyPatternsAndFoldGreedily(getFunction(), std::move(patterns));
717717
}
718718
};
719719

mlir/lib/Dialect/Affine/Transforms/AffineDataCopyGeneration.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ AffineDataCopyGeneration::runOnBlock(Block *block,
155155
if (recurseInner) {
156156
// We'll recurse and do the copies at an inner level for 'forInst'.
157157
// Recurse onto the body of this loop.
158-
runOnBlock(forOp.getBody(), copyNests);
158+
(void)runOnBlock(forOp.getBody(), copyNests);
159159
} else {
160160
// We have enough capacity, i.e., copies will be computed for the
161161
// portion of the block until 'it', and for 'it', which is 'forOp'. Note
@@ -207,7 +207,7 @@ void AffineDataCopyGeneration::runOnFunction() {
207207
copyNests.clear();
208208

209209
for (auto &block : f)
210-
runOnBlock(&block, copyNests);
210+
(void)runOnBlock(&block, copyNests);
211211

212212
// Promote any single iteration loops in the copy nests and collect
213213
// load/stores to simplify.
@@ -217,7 +217,7 @@ void AffineDataCopyGeneration::runOnFunction() {
217217
// continuation of the walk or the collection of load/store ops.
218218
nest->walk([&](Operation *op) {
219219
if (auto forOp = dyn_cast<AffineForOp>(op))
220-
promoteIfSingleIteration(forOp);
220+
(void)promoteIfSingleIteration(forOp);
221221
else if (isa<AffineLoadOp, AffineStoreOp>(op))
222222
copyOps.push_back(op);
223223
});
@@ -230,5 +230,5 @@ void AffineDataCopyGeneration::runOnFunction() {
230230
AffineStoreOp::getCanonicalizationPatterns(patterns, &getContext());
231231
FrozenRewritePatternList frozenPatterns(std::move(patterns));
232232
for (Operation *op : copyOps)
233-
applyOpPatternsAndFold(op, frozenPatterns);
233+
(void)applyOpPatternsAndFold(op, frozenPatterns);
234234
}

0 commit comments

Comments
 (0)