Burst compile-time optimzation

One of my favorite C++ features is compile-time optimization with constant expressions, I know that maybe it’s to early to purpose something like this but I wanna know if It’s possible in the future to have something like this or nah:

[BurstCompile]
public struct JobExample<T> : IJob where T : IComponentData
{
   public void Execute()
   {
      if (IsFoo())
      {
         int Value = GetBar(); // GetBar() will be replaced by the value calculated at compile-time
         // this block will only be compiled if IsFoo is true at compile-time
      }
   }
   [BurstConstantExpression]
   public bool IsFoo()
   {
      return typeof(IFoo).IsAssignableFrom(typeof(T));
   }
   [BurstConstantExpression]
   public int GetBar()
   {
      var Attributes = typeof(T).GetCustomAttributes(typeof(BarAttribute)) as BarAttribute[];
      return Attributes[0].Value;
   }
}
}
2 Likes

Burst uses LLVM under the covers, and LLVM is very good at constant folding. In your particular example, Burst doesn’t support typeof. But if IsFoo() contained only Burst-compatible code that can be evaluated at compile-time, then what you’re after will already happen with the current Burst compiler - the block inside if IsFoo() will only be compiled if it evaluates to true at compile-time.

On the other hand, constexpr is nice because the compiler gives an error if something can’t be evaluated at compile-time, and we don’t have that today in Burst, which may be what you’re asking for. Interesting idea, I’ll take it to the team.

1 Like

My suggestion was to evaluate the expression in Mono/IL2CPP then use the results as constants, that’s why I’m using typeof, It would be nice to extract some type traits to get better performance.

Maybe this feature is not that hard to implement because if the burst input is IL code then it’s possible to check whether the method (operand) of a call op contains a specific attribute and if that is the case (it supports only static method) so its return value is stored for later use and all call to this method will be replace by a constant

1 Like