[llvm-dev] ThinLTO + CFI

via llvm-dev llvm-dev at lists.llvm.org
Mon Apr 9 10:51:01 PDT 2018


Hi,

I’m working on setting up ThinLTO+CFI for a C application which uses a lot of function pointers. While functionally it appears stable, it’s performance is significantly degraded, to the tune of double digit percentage points compared to regular LTO+CFI.

Looking into possible causes I see that under ThinLTO+CFI iCall type checks almost always generate jump table entries for indirect calls, which creates another level of indirection for every such call. On top of that it breaks the link order layout because real function names point to jump table entries. It appears that I’m hitting a limitation in ThinLTO on how much information it can propagate across modules, particularly information about constants. In the example below, the fact that “i” is effectively a constant, is lost under ThinLTO, and the inlined copy of b.c:get_fptr() in a.c does not eliminate the conditional, which, for CFI purposes requires to generate a type check/jump table.

I was wondering if there was a way to mitigate this limitation.

a.c
=============================
typedef int (*fptr_t) (void);
fptr_t get_fptr();
int main(int argc, char *argv[])
{
  fptr_t fp = get_fptr();
  return fp();
}


b.c
=============================
typedef int (*fptr_t) (void);
int foo(void) { return 11; }
int bar(void) { return 22; }

static fptr_t fptr = bar;
static int i = 53;

fptr_t get_fptr(void)
{
  if (i >= 0)
    fptr = foo;
  else
    fptr = bar;

  return fptr;
}



More information about the llvm-dev mailing list