RFC: support getAnalysis<AnalysisT, OpTy> function from passes?

MLIR’s support for constructing and caching analysis objects seems to only allow constructing analysis objects with a constructor that takes an Operation *. In cases where an analysis is expected to work only with a certain object type, like a FuncOp or a ModuleOp, it would be ideal to have the constructor expect an object of that kind and non-conforming uses fail to compile.

Looking into some of the existing Analysis objects, they seems pretty generic in terms of what operations that work on. However, I have out-of-tree cases where the analysis objects expect a FuncOp or ModuleOp. They current code does a dyn_cast<> and assert if the Operation provided is not of the desired type. I was hoping we could do either of these things to help make this a compile time error:

  1. Override getAnalysis() for OperationPass such that it call’s the analysis constructor with the Op casted to OpT for that operation pass. However, it seems existing passes that take Operation* may not work then with OperationPass which is not desirable, and we want to keep these analysis generic

  2. So instead of (1), expose a getAnalysis<AnalysisT, OpT> function on the Pass class. If someone attempts to call getAnalysis<AnalysisT>, it will fail to compile if the analysis object does not provide a constructor that takes an Operation *. Also, if OpT is not of the correct type, it will fail to compile as well.

FYI, I have started a review implementing (1): https://reviews.llvm.org/D84897