hfinkel / llvm-project-cxxjit

Clang with JIT extensions
https://github.com/hfinkel/llvm-project-cxxjit/wiki
229 stars 23 forks source link

Jitting variadic int packs segfaults the compiler (at runtime) #2

Closed DavidPoliakoff closed 5 years ago

DavidPoliakoff commented 5 years ago

Hey Hal,

I'm working on a simple wrapping layer to hide JIT when it isn't available. The idea is that you'll pass in a region to JIT, and the values to JIT into it. The region should accept one int argument per jitted value. If JIT exists, we use those as the template arguments to a [[clang::jit]] decorated function which calls that lambda with values which I hope the compiler will recognize as constant. If JIT doesn't exist, we'll instead just call the lambda with the runtime values, making a transparent interface which hides the JIT from users. A quick code sample (note: I don't have the "I don't have JIT" branch written, I want to get this branch working first).

template<int... Jitted, typename LB>
[[clang::jit]] void jittable_func(LB body){
  body(Jitted...);
}

template<typename LB, typename... Args>
void jit_region(LB body, Args... args){
  jittable_func<args...>(body);
}

struct test{};
int main(){
  int x = 5;
  jit_region(
      [](const int perhaps_jitted_two, const int perhaps_jitted_four){
         int sixplus = perhaps_jitted_two + perhaps_jitted_four;
      },
      2,
      4
      );
}

If I have this, I can write a layer in RAJA to automatically JIT loop bounds to RAJA's "forall" (parallel_for) construct, or even the more advanced kernel construct, and then we just start pushing LLNL apps through that version of RAJA and collecting performance data.

DavidPoliakoff commented 5 years ago

@hfinkel : I spaced. The actual error I get at runtime is

DeclRefExpr for Decl not entered in LocalDeclMap?
UNREACHABLE executed at /usr/workspace/wsrzd/dzpolia/src/llvm-project-cxxjit/clang/lib/CodeGen/CGExpr.cpp:2710!
Aborted (core dumped)
DavidPoliakoff commented 5 years ago

Please excuse the many quick comments, I'm trying workarounds, and hope the different error messages might make this easier to debug. I tried to fix the number of specialized values at 2, to see if it was the variadic part that was giving us trouble.

template<int val1, int val2, typename LB>
[[clang::jit]] void jittable_func2(LB body){
  body(val1, val2);
}

template<typename LB, typename... Args>
void jit_region(LB body, Args... args){
  jittable_func2<args...,LB>(body);
}

struct test{};
int main(){
  int x = 5;
  jit_region(
      [](const int perhaps_jitted_two, const int perhaps_jitted_four){
         int sixplusx = perhaps_jitted_two + perhaps_jitted_four;
      },
      2,
      4
      );
}

I've tried calling jittable_func2 with and without naming LB, and in each case get a different error message than the variadic case

bash-4.2$ ./jittable_sample
jittable_sample: /usr/workspace/wsrzd/dzpolia/src/llvm-project-cxxjit/clang/lib/CodeGen/JIT.cpp:1067: void *(anonymous namespace)::CompilerData::resolveFunction(const void *, const char **, unsigned int): Assertion `SpecSymbol && "Can't find the specialization just generated?"' failed.
Aborted (core dumped)
hfinkel commented 5 years ago

Packs with dynamic arguments weren't supported at all. Should be fixed now. Please verify.

DavidPoliakoff commented 5 years ago

This is super weird, I pulled this morning and still have the problem. I looked at your test, and it's exactly my code. I'll try to debug further, but I'm still using

template<int... Jitted, typename LB>
[[clang::jit]] void jittable_func(LB body){
  body(Jitted...);
}

template<typename LB, typename... Args>
void jit_region(LB body, Args... args){
  jittable_func<args...>(body);
}

int main(){
  jit_region(
      [](const int perhaps_jitted_two, const int perhaps_jitted_four){
         int sixplusx = perhaps_jitted_two + perhaps_jitted_four;
      },
      2,
      4
      );
}

And getting

jittable_sample: /usr/workspace/wsrzd/dzpolia/src/llvm-project-cxxjit/clang/lib/CodeGen/JIT.cpp:1090: void *(anonymous namespace)::CompilerData::resolveFunction(const void *, const char **, unsigned int): Assertion `SpecSymbol && "Can't find the specialization just generated?"' failed.

EDIT: it's the optimization level. This fails at -O3, succeeds at -O0. Looks like it fails at O2 as well :(

hfinkel commented 5 years ago

Indeed, thanks! Please check again.

DavidPoliakoff commented 5 years ago

This works now, thanks Hal