xref: /aosp_15_r20/external/executorch/kernels/optimized/utils/unroll.h (revision 523fa7a60841cd1ecfb9cc4201f1ca8b03ed023a)
1*523fa7a6SAndroid Build Coastguard Worker /*
2*523fa7a6SAndroid Build Coastguard Worker  * Copyright (c) Meta Platforms, Inc. and affiliates.
3*523fa7a6SAndroid Build Coastguard Worker  * All rights reserved.
4*523fa7a6SAndroid Build Coastguard Worker  *
5*523fa7a6SAndroid Build Coastguard Worker  * This source code is licensed under the BSD-style license found in the
6*523fa7a6SAndroid Build Coastguard Worker  * LICENSE file in the root directory of this source tree.
7*523fa7a6SAndroid Build Coastguard Worker  */
8*523fa7a6SAndroid Build Coastguard Worker 
9*523fa7a6SAndroid Build Coastguard Worker #pragma once
10*523fa7a6SAndroid Build Coastguard Worker 
11*523fa7a6SAndroid Build Coastguard Worker #include <executorch/runtime/platform/compiler.h>
12*523fa7a6SAndroid Build Coastguard Worker 
13*523fa7a6SAndroid Build Coastguard Worker // Utility to guaruntee complete unrolling of a loop where the bounds are known
14*523fa7a6SAndroid Build Coastguard Worker // at compile time. Various pragmas achieve similar effects, but are not as
15*523fa7a6SAndroid Build Coastguard Worker // portable across compilers.
16*523fa7a6SAndroid Build Coastguard Worker 
17*523fa7a6SAndroid Build Coastguard Worker // Example: ForcedUnroll<4>{}(f); is equivalent to f(0); f(1); f(2); f(3);
18*523fa7a6SAndroid Build Coastguard Worker 
19*523fa7a6SAndroid Build Coastguard Worker namespace executorch {
20*523fa7a6SAndroid Build Coastguard Worker namespace utils {
21*523fa7a6SAndroid Build Coastguard Worker 
22*523fa7a6SAndroid Build Coastguard Worker template <int n>
23*523fa7a6SAndroid Build Coastguard Worker struct ForcedUnroll {
24*523fa7a6SAndroid Build Coastguard Worker   template <typename Func>
operatorForcedUnroll25*523fa7a6SAndroid Build Coastguard Worker   ET_INLINE void operator()(const Func& f) const {
26*523fa7a6SAndroid Build Coastguard Worker     ForcedUnroll<n - 1>{}(f);
27*523fa7a6SAndroid Build Coastguard Worker     f(n - 1);
28*523fa7a6SAndroid Build Coastguard Worker   }
29*523fa7a6SAndroid Build Coastguard Worker };
30*523fa7a6SAndroid Build Coastguard Worker 
31*523fa7a6SAndroid Build Coastguard Worker template <>
32*523fa7a6SAndroid Build Coastguard Worker struct ForcedUnroll<1> {
33*523fa7a6SAndroid Build Coastguard Worker   template <typename Func>
34*523fa7a6SAndroid Build Coastguard Worker   ET_INLINE void operator()(const Func& f) const {
35*523fa7a6SAndroid Build Coastguard Worker     f(0);
36*523fa7a6SAndroid Build Coastguard Worker   }
37*523fa7a6SAndroid Build Coastguard Worker };
38*523fa7a6SAndroid Build Coastguard Worker 
39*523fa7a6SAndroid Build Coastguard Worker } // namespace utils
40*523fa7a6SAndroid Build Coastguard Worker } // namespace executorch
41