[llvm] [RFC][LV] VPlan-based cost model (PR #67647)

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Sun Apr 28 05:48:02 PDT 2024


fhahn wrote:


> 
> @fhahn Even though I understand adding `::computeCost` to `VPlan`/`VPRecipe`/`VPInstruction`/etc is aligned with current design of a `VPlan` which has `::execute` methods there. However, cost model is usually what downstream compilers modify and may not want to upstream due to the policies. With that, a dedicated object for the cost model that takes VPlan and computes the cost of it makes life easier for downstream compilers to modify code without adding to much pain to pulldowns. That is, if upstream compiler has a base version
> 
> ```c++
> class VPlanCostModel {
>   virtual int64_t getCost(VPlanPtr);
>   virtual int64_t getCost(VPInstruction *VPInst);
>   ...
> };
> ```
> 
> downstream compiler, if it wants to have its own implementation may override some of these functions:
> 
> ```c++
> class VPlanCostModelDownstream : public VPlanCostModel {
>   int64_t getCost(VPInstruction *VPInst) override;
>   ...
> };
> ```
> 
> with minor change when VPCM is constructed. In both cases extra object is necessary, but entire state/context of the cost model is isolated in `VPlanCostModel`.
>

At the moment, computing costs is framed in terms of the IR instructions we generate (i.e.  what `::execute` will generate) and target-specific info is pulled in via TTI only. In that sense, I think it makes sense to keep them defined in the same place. Do you by any chance have some examples where TTI would not be sufficient for downstream customizations?

In general, I think `llvm` tries to limit target-specific customizations in the middle-end to TTI and possibly via intrinsics to encourage as much code-sharing upstream as possible. I am not aware of other areas in the middle-end where other means are provided to customize for downstream users explicitly, although I may be missing something and I don't think it is an official policy that's spelled out anywhere.

 
> btw, do you know why `::execute` methods were added to a VPlan instead of having something like `VPlanCodeGen` ?

I think the original motivation was to have codegen for each recipe in the recipes directly, as it is strongly tied to the semantics of the recipe and ensure that it is easy to see what the implementation of the recipe looks like in terms of codegen.

> > > General idea seems sound, but this needs tests to convince me that LV behavior doesn't change with VPlan-based costing.
> The cost model has moved inside the VPlan infrastructure and is no longer called from the same place in the same way. Please provide evidence that, even without the vplan-based cost model flag, the behaviour of the vectorizer hasn't changed.
> 
> Performance numbers on some benchmarks, traces on the test-suite showing what gets vectorized and what doesn't, etc.
> 
> If this is just about the migration, then it should behave in the same way as before without the optional flag.

Finally had time to get https://github.com/llvm/llvm-project/pull/67934 updated to a version that has the VPlan-based and legacy cost-models agree on the VF for large code-bases (llvm-test-suite, SPEC2017, Clang bootstrap) and multiple configurations (AArch64 with/wo SVE, with/wo `-prefer-predicate-over-epilogue=predicate-else-scalar-epilogue`, X86 with AVX512). In the PR, the VPlan-based cost-model is used to select the VF and best plan. Note it still falls back to the legacy cost-model for most cases (VPlan-based costing is implemented for VPWidenRecipe initially), but allows gradually transitioning.

https://github.com/llvm/llvm-project/pull/67647


More information about the llvm-commits mailing list