mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-03-01 06:46:34 +00:00
[mlir][SideEffects] Mark the CFG only terminator operations as NoSideEffect
These terminator operations don't really have any side effects, and this allows for more accurate side-effect analysis for region operations. For example, currently we can't detect like a loop.for or affine.for are dead because the affine.terminator is "side effecting". Note: Marking as NoSideEffect doesn't mean that these operations can be opaquely erased. Differential Revision: https://reviews.llvm.org/D75888
This commit is contained in:
parent
56926a9146
commit
d5f53253a0
@ -190,7 +190,8 @@ def ReshapeOp : Toy_Op<"reshape"> {
|
||||
}];
|
||||
}
|
||||
|
||||
def ReturnOp : Toy_Op<"return", [Terminator, HasParent<"FuncOp">]> {
|
||||
def ReturnOp : Toy_Op<"return", [NoSideEffect, HasParent<"FuncOp">,
|
||||
Terminator]> {
|
||||
let summary = "return operation";
|
||||
let description = [{
|
||||
The "return" operation represents a return operation within a function.
|
||||
|
@ -193,7 +193,8 @@ def ReshapeOp : Toy_Op<"reshape", [NoSideEffect]> {
|
||||
let hasCanonicalizer = 1;
|
||||
}
|
||||
|
||||
def ReturnOp : Toy_Op<"return", [Terminator, HasParent<"FuncOp">]> {
|
||||
def ReturnOp : Toy_Op<"return", [NoSideEffect, HasParent<"FuncOp">,
|
||||
Terminator]> {
|
||||
let summary = "return operation";
|
||||
let description = [{
|
||||
The "return" operation represents a return operation within a function.
|
||||
|
@ -218,7 +218,8 @@ def ReshapeOp : Toy_Op<"reshape", [NoSideEffect]> {
|
||||
let hasCanonicalizer = 1;
|
||||
}
|
||||
|
||||
def ReturnOp : Toy_Op<"return", [Terminator, HasParent<"FuncOp">]> {
|
||||
def ReturnOp : Toy_Op<"return", [NoSideEffect, HasParent<"FuncOp">,
|
||||
Terminator]> {
|
||||
let summary = "return operation";
|
||||
let description = [{
|
||||
The "return" operation represents a return operation within a function.
|
||||
|
@ -219,7 +219,8 @@ def ReshapeOp : Toy_Op<"reshape", [NoSideEffect]> {
|
||||
let hasCanonicalizer = 1;
|
||||
}
|
||||
|
||||
def ReturnOp : Toy_Op<"return", [Terminator, HasParent<"FuncOp">]> {
|
||||
def ReturnOp : Toy_Op<"return", [NoSideEffect, HasParent<"FuncOp">,
|
||||
Terminator]> {
|
||||
let summary = "return operation";
|
||||
let description = [{
|
||||
The "return" operation represents a return operation within a function.
|
||||
|
@ -219,7 +219,8 @@ def ReshapeOp : Toy_Op<"reshape", [NoSideEffect]> {
|
||||
let results = (outs StaticShapeTensorOf<[F64]>);
|
||||
}
|
||||
|
||||
def ReturnOp : Toy_Op<"return", [Terminator, HasParent<"FuncOp">]> {
|
||||
def ReturnOp : Toy_Op<"return", [NoSideEffect, HasParent<"FuncOp">,
|
||||
Terminator]> {
|
||||
let summary = "return operation";
|
||||
let description = [{
|
||||
The "return" operation represents a return operation within a function.
|
||||
|
@ -232,7 +232,8 @@ def ReshapeOp : Toy_Op<"reshape", [NoSideEffect]> {
|
||||
let results = (outs StaticShapeTensorOf<[F64]>);
|
||||
}
|
||||
|
||||
def ReturnOp : Toy_Op<"return", [Terminator, HasParent<"FuncOp">]> {
|
||||
def ReturnOp : Toy_Op<"return", [NoSideEffect, HasParent<"FuncOp">,
|
||||
Terminator]> {
|
||||
let summary = "return operation";
|
||||
let description = [{
|
||||
The "return" operation represents a return operation within a function.
|
||||
|
@ -433,7 +433,7 @@ def AffinePrefetchOp : Affine_Op<"prefetch"> {
|
||||
}
|
||||
|
||||
def AffineTerminatorOp :
|
||||
Affine_Op<"terminator", [Terminator]> {
|
||||
Affine_Op<"terminator", [NoSideEffect, Terminator]> {
|
||||
let summary = "affine terminator operation";
|
||||
let description = [{
|
||||
Affine terminator is a special terminator operation for blocks inside affine
|
||||
|
@ -439,7 +439,8 @@ def GPU_LaunchOp : GPU_Op<"launch">,
|
||||
let verifier = [{ return ::verify(*this); }];
|
||||
}
|
||||
|
||||
def GPU_ReturnOp : GPU_Op<"return", [HasParent<"GPUFuncOp">, Terminator]>,
|
||||
def GPU_ReturnOp : GPU_Op<"return", [HasParent<"GPUFuncOp">, NoSideEffect,
|
||||
Terminator]>,
|
||||
Arguments<(ins Variadic<AnyType>:$operands)>, Results<(outs)> {
|
||||
let summary = "Terminator for GPU functions.";
|
||||
let description = [{
|
||||
@ -455,7 +456,8 @@ def GPU_ReturnOp : GPU_Op<"return", [HasParent<"GPUFuncOp">, Terminator]>,
|
||||
let verifier = [{ return ::verify(*this); }];
|
||||
}
|
||||
|
||||
def GPU_TerminatorOp : GPU_Op<"terminator", [HasParent<"LaunchOp">, Terminator]>,
|
||||
def GPU_TerminatorOp : GPU_Op<"terminator", [HasParent<"LaunchOp">,
|
||||
NoSideEffect, Terminator]>,
|
||||
Arguments<(ins)>, Results<(outs)> {
|
||||
let summary = "Terminator for GPU launch regions.";
|
||||
let description = [{
|
||||
@ -468,7 +470,7 @@ def GPU_TerminatorOp : GPU_Op<"terminator", [HasParent<"LaunchOp">, Terminator]>
|
||||
let printer = [{ p << getOperationName(); }];
|
||||
}
|
||||
|
||||
def GPU_YieldOp : GPU_Op<"yield", [Terminator]>,
|
||||
def GPU_YieldOp : GPU_Op<"yield", [NoSideEffect, Terminator]>,
|
||||
Arguments<(ins Variadic<AnyType>:$values)> {
|
||||
let summary = "GPU yield operation";
|
||||
let description = [{
|
||||
|
@ -452,7 +452,7 @@ def LLVM_FreezeOp : LLVM_OneResultOp<"freeze", [SameOperandsAndResultType]>,
|
||||
|
||||
// Terminators.
|
||||
def LLVM_BrOp : LLVM_TerminatorOp<"br",
|
||||
[DeclareOpInterfaceMethods<BranchOpInterface>]> {
|
||||
[DeclareOpInterfaceMethods<BranchOpInterface>, NoSideEffect]> {
|
||||
let arguments = (ins Variadic<LLVM_Type>:$destOperands);
|
||||
let successors = (successor AnySuccessor:$dest);
|
||||
let assemblyFormat = [{
|
||||
@ -461,7 +461,8 @@ def LLVM_BrOp : LLVM_TerminatorOp<"br",
|
||||
let builders = [LLVM_TerminatorPassthroughOpBuilder];
|
||||
}
|
||||
def LLVM_CondBrOp : LLVM_TerminatorOp<"cond_br",
|
||||
[AttrSizedOperandSegments, DeclareOpInterfaceMethods<BranchOpInterface>]> {
|
||||
[AttrSizedOperandSegments, DeclareOpInterfaceMethods<BranchOpInterface>,
|
||||
NoSideEffect]> {
|
||||
let arguments = (ins LLVMI1:$condition,
|
||||
Variadic<LLVM_Type>:$trueDestOperands,
|
||||
Variadic<LLVM_Type>:$falseDestOperands);
|
||||
@ -486,7 +487,7 @@ def LLVM_CondBrOp : LLVM_TerminatorOp<"cond_br",
|
||||
falseOperands);
|
||||
}]>, LLVM_TerminatorPassthroughOpBuilder];
|
||||
}
|
||||
def LLVM_ReturnOp : LLVM_TerminatorOp<"return", []>,
|
||||
def LLVM_ReturnOp : LLVM_TerminatorOp<"return", [NoSideEffect]>,
|
||||
Arguments<(ins Variadic<LLVM_Type>:$args)> {
|
||||
string llvmBuilder = [{
|
||||
if ($_numOperands != 0)
|
||||
|
@ -233,7 +233,7 @@ def Linalg_TransposeOp : Linalg_Op<"transpose", [NoSideEffect]>,
|
||||
let hasFolder = 1;
|
||||
}
|
||||
|
||||
def Linalg_YieldOp : Linalg_Op<"yield", [NativeOpTrait<"IsTerminator">]>,
|
||||
def Linalg_YieldOp : Linalg_Op<"yield", [NoSideEffect, Terminator]>,
|
||||
Arguments<(ins Variadic<AnyType>:$values)> {
|
||||
let summary = "Linalg yield operation";
|
||||
let description = [{
|
||||
|
@ -360,7 +360,8 @@ def ReduceOp : Loop_Op<"reduce", [HasParent<"ParallelOp">]> {
|
||||
}
|
||||
|
||||
def ReduceReturnOp :
|
||||
Loop_Op<"reduce.return", [HasParent<"ReduceOp">, Terminator]> {
|
||||
Loop_Op<"reduce.return", [HasParent<"ReduceOp">, NoSideEffect,
|
||||
Terminator]> {
|
||||
let summary = "terminator for reduce operation";
|
||||
let description = [{
|
||||
"loop.reduce.return" is a special terminator operation for the block inside
|
||||
@ -376,7 +377,7 @@ def ReduceReturnOp :
|
||||
let assemblyFormat = "$result attr-dict `:` type($result)";
|
||||
}
|
||||
|
||||
def YieldOp : Loop_Op<"yield", [Terminator]> {
|
||||
def YieldOp : Loop_Op<"yield", [NoSideEffect, Terminator]> {
|
||||
let summary = "loop yield and termination operation";
|
||||
let description = [{
|
||||
"loop.yield" yields an SSA value from a loop dialect op region and
|
||||
|
@ -21,7 +21,7 @@ include "mlir/Interfaces/ControlFlowInterfaces.td"
|
||||
// -----
|
||||
|
||||
def SPV_BranchOp : SPV_Op<"Branch", [
|
||||
DeclareOpInterfaceMethods<BranchOpInterface>, InFunctionScope,
|
||||
DeclareOpInterfaceMethods<BranchOpInterface>, InFunctionScope, NoSideEffect,
|
||||
Terminator]> {
|
||||
let summary = "Unconditional branch to target block.";
|
||||
|
||||
@ -83,7 +83,7 @@ def SPV_BranchOp : SPV_Op<"Branch", [
|
||||
|
||||
def SPV_BranchConditionalOp : SPV_Op<"BranchConditional", [
|
||||
AttrSizedOperandSegments, DeclareOpInterfaceMethods<BranchOpInterface>,
|
||||
InFunctionScope, Terminator]> {
|
||||
InFunctionScope, NoSideEffect, Terminator]> {
|
||||
let summary = [{
|
||||
If Condition is true, branch to true block, otherwise branch to false
|
||||
block.
|
||||
@ -316,7 +316,7 @@ def SPV_LoopOp : SPV_Op<"loop", [InFunctionScope]> {
|
||||
|
||||
// -----
|
||||
|
||||
def SPV_MergeOp : SPV_Op<"_merge", [Terminator]> {
|
||||
def SPV_MergeOp : SPV_Op<"_merge", [NoSideEffect, Terminator]> {
|
||||
let summary = "A special terminator for merging a structured selection/loop.";
|
||||
|
||||
let description = [{
|
||||
@ -340,7 +340,8 @@ def SPV_MergeOp : SPV_Op<"_merge", [Terminator]> {
|
||||
|
||||
// -----
|
||||
|
||||
def SPV_ReturnOp : SPV_Op<"Return", [InFunctionScope, Terminator]> {
|
||||
def SPV_ReturnOp : SPV_Op<"Return", [InFunctionScope, NoSideEffect,
|
||||
Terminator]> {
|
||||
let summary = "Return with no value from a function with void return type.";
|
||||
|
||||
let description = [{
|
||||
@ -384,7 +385,8 @@ def SPV_UnreachableOp : SPV_Op<"Unreachable", [InFunctionScope, Terminator]> {
|
||||
|
||||
// -----
|
||||
|
||||
def SPV_ReturnValueOp : SPV_Op<"ReturnValue", [InFunctionScope, Terminator]> {
|
||||
def SPV_ReturnValueOp : SPV_Op<"ReturnValue", [InFunctionScope, NoSideEffect,
|
||||
Terminator]> {
|
||||
let summary = "Return a value from a function.";
|
||||
|
||||
let description = [{
|
||||
|
@ -334,7 +334,7 @@ def AtomicRMWOp : Std_Op<"atomic_rmw", [
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def BranchOp : Std_Op<"br",
|
||||
[DeclareOpInterfaceMethods<BranchOpInterface>, Terminator]> {
|
||||
[DeclareOpInterfaceMethods<BranchOpInterface>, NoSideEffect, Terminator]> {
|
||||
let summary = "branch operation";
|
||||
let description = [{
|
||||
The "br" operation represents a branch operation in a function.
|
||||
@ -678,7 +678,7 @@ def CmpIOp : Std_Op<"cmpi",
|
||||
|
||||
def CondBranchOp : Std_Op<"cond_br",
|
||||
[AttrSizedOperandSegments, DeclareOpInterfaceMethods<BranchOpInterface>,
|
||||
Terminator]> {
|
||||
NoSideEffect, Terminator]> {
|
||||
let summary = "conditional branch operation";
|
||||
let description = [{
|
||||
The "cond_br" operation represents a conditional branch operation in a
|
||||
@ -1288,7 +1288,8 @@ def RemFOp : FloatArithmeticOp<"remf"> {
|
||||
// ReturnOp
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def ReturnOp : Std_Op<"return", [Terminator, HasParent<"FuncOp">]> {
|
||||
def ReturnOp : Std_Op<"return", [NoSideEffect, HasParent<"FuncOp">,
|
||||
Terminator]> {
|
||||
let summary = "return operation";
|
||||
let description = [{
|
||||
The "return" operation represents a return operation within a function.
|
||||
|
@ -123,6 +123,10 @@ private:
|
||||
|
||||
/// Attempt to eliminate a redundant operation.
|
||||
LogicalResult CSE::simplifyOperation(ScopedMapTy &knownValues, Operation *op) {
|
||||
// Don't simplify terminator operations.
|
||||
if (op->isKnownTerminator())
|
||||
return failure();
|
||||
|
||||
// Don't simplify operations with nested blocks. We don't currently model
|
||||
// equality comparisons correctly among other things. It is also unclear
|
||||
// whether we would want to CSE such operations.
|
||||
|
@ -164,7 +164,8 @@ bool GreedyPatternRewriteDriver::simplify(MutableArrayRef<Region> regions,
|
||||
|
||||
// If the operation has no side effects, and no users, then it is
|
||||
// trivially dead - remove it.
|
||||
if (op->hasNoSideEffect() && op->use_empty()) {
|
||||
if (op->isKnownNonTerminator() && op->hasNoSideEffect() &&
|
||||
op->use_empty()) {
|
||||
// Be careful to update bookkeeping.
|
||||
notifyOperationRemoved(op);
|
||||
op->erase();
|
||||
|
@ -868,7 +868,7 @@ static LogicalResult hoistOpsBetween(loop::ForOp outer, loop::ForOp inner) {
|
||||
});
|
||||
LogicalResult status = success();
|
||||
SmallVector<Operation *, 8> toHoist;
|
||||
for (auto &op : outer.getBody()->getOperations()) {
|
||||
for (auto &op : outer.getBody()->without_terminator()) {
|
||||
// Stop when encountering the inner loop.
|
||||
if (&op == inner.getOperation())
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user