================
@@ -20,17 +21,117 @@ using namespace cir;
// Helpers
//===----------------------------------------------------------------------===//
+static constexpr unsigned MaxLookupDepth = 6;
+
mlir::Value CIRBasicAliasAnalysis::getUnderlyingObject(mlir::Value val) {
LDBG() << "Getting underlying object for: " << val;
- // TODO: Walk through cir.ptr_stride, cir.cast, cir.get_member, etc.
- // to find the root allocation (cir.alloca, cir.global_addr, function args).
- LDBG() << "Not yet implemented";
+ for (unsigned depth = 0; depth < MaxLookupDepth; ++depth) {
+ mlir::Operation *defOp = val.getDefiningOp();
+ if (!defOp) {
+ LDBG() << "No defining operation, stopping";
+ break; // Block argument (e.g. function parameter) — stop here.
+ }
+
+ // Bitcast and address-space casts don't change the underlying object.
+ // array_to_ptrdecay produces an element pointer to the same storage as
+ // the array pointer, so strip through it too.
+ if (auto castOp = mlir::dyn_cast<cir::CastOp>(defOp)) {
----------------
bcardosolopes wrote:
Overall, I think the handling of each operation should be in its own method,
and should return a sort of state/enum, that is then used to continue/break. As
separated methods (a) the loop body becomes smaller, (b) inside each method
it's easier to early return if there are cascading conditions, (c) in the
future we could put the handling in .td files for each op.
https://github.com/llvm/llvm-project/pull/215683
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits