[Mlir-commits] [mlir] MLIR, LLVM: Add an IR utility to perform proper slicing (PR #103053)
Tobias Gysi
llvmlistbot at llvm.org
Tue Aug 13 06:16:43 PDT 2024
================
@@ -221,86 +222,28 @@ static ArrayAttr concatArrayAttr(ArrayAttr lhs, ArrayAttr rhs) {
return ArrayAttr::get(lhs.getContext(), result);
}
-/// Attempts to return the underlying pointer value that `pointerValue` is based
-/// on. This traverses down the chain of operations to the last operation
-/// producing the base pointer and returns it. If it encounters an operation it
-/// cannot further traverse through, returns the operation's result.
-static Value getUnderlyingObject(Value pointerValue) {
- while (true) {
- if (auto gepOp = pointerValue.getDefiningOp<LLVM::GEPOp>()) {
- pointerValue = gepOp.getBase();
- continue;
- }
-
- if (auto addrCast = pointerValue.getDefiningOp<LLVM::AddrSpaceCastOp>()) {
- pointerValue = addrCast.getOperand();
- continue;
- }
-
- break;
- }
-
- return pointerValue;
-}
-
/// Attempts to return the set of all underlying pointer values that
/// `pointerValue` is based on. This function traverses through select
/// operations and block arguments unlike getUnderlyingObject.
static SmallVector<Value> getUnderlyingObjectSet(Value pointerValue) {
SmallVector<Value> result;
+ walkBackwardSlice(pointerValue, [&](Value val) {
+ if (auto gepOp = val.getDefiningOp<LLVM::GEPOp>())
+ return WalkContinuation::advanceTo(gepOp.getBase());
- SmallVector<Value> workList{pointerValue};
- // Avoid dataflow loops.
- SmallPtrSet<Value, 4> seen;
- do {
- Value current = workList.pop_back_val();
- current = getUnderlyingObject(current);
-
- if (!seen.insert(current).second)
- continue;
-
- if (auto selectOp = current.getDefiningOp<LLVM::SelectOp>()) {
- workList.push_back(selectOp.getTrueValue());
- workList.push_back(selectOp.getFalseValue());
- continue;
- }
-
- if (auto blockArg = dyn_cast<BlockArgument>(current)) {
- Block *parentBlock = blockArg.getParentBlock();
-
- // Attempt to find all block argument operands for every predecessor.
- // If any operand to the block argument wasn't found in a predecessor,
- // conservatively add the block argument to the result set.
- SmallVector<Value> operands;
- bool anyUnknown = false;
- for (auto iter = parentBlock->pred_begin();
- iter != parentBlock->pred_end(); iter++) {
- auto branch = dyn_cast<BranchOpInterface>((*iter)->getTerminator());
- if (!branch) {
- result.push_back(blockArg);
- anyUnknown = true;
- break;
- }
-
- Value operand = branch.getSuccessorOperands(
- iter.getSuccessorIndex())[blockArg.getArgNumber()];
- if (!operand) {
- result.push_back(blockArg);
- anyUnknown = true;
- break;
- }
-
- operands.push_back(operand);
- }
+ if (auto addrCast = val.getDefiningOp<LLVM::AddrSpaceCastOp>())
+ return WalkContinuation::advanceTo(addrCast.getOperand());
- if (!anyUnknown)
- llvm::append_range(workList, operands);
+ // TODO: Add a SelectLikeOpInterface and use it in the slicing utility.
+ if (auto selectOp = val.getDefiningOp<LLVM::SelectOp>())
+ return WalkContinuation::advanceTo(
+ {selectOp.getTrueValue(), selectOp.getFalseValue()});
- continue;
- }
+ if (isa<OpResult>(val))
----------------
gysit wrote:
At least function arguments should probably be added as well? The cleaner solution maybe to check if the block arguments do not belong to a RegionBranchOp or are not have a BranchOpInterface predecessor add them to the result array and return skip?
https://github.com/llvm/llvm-project/pull/103053
More information about the Mlir-commits
mailing list