[PATCH] D74651: Add IR constructs for inalloca replacement preallocated call setup

Eli Friedman via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 27 17:16:41 PDT 2020


efriedma added a comment.

> This looks like loop re-rolling to me, though, to give the transform a name.

Yes, that's the idea.  (LLVM has a reroll pass, but it only handles rerolling loops.)

I guess I'll try to construct an actual C++ example.  Suppose you have something like this:

  extern "C" int printf(const char*, ...);
  extern "C" void abort(void) __attribute((noreturn));
  struct A;
  A* ptrs[10];
  struct A {
      int z;
      __attribute((noinline))
      A(int x) { z = 1; ptrs[z] = this; }
      A(const A&);
  };
      __attribute((noinline))
  void sum() { int sum = 0; for(A* p : ptrs) sum += p->z; printf("%d\n", sum); }
  int g(int, A);
  void f() { g(g(g(g(g((sum(), abort(), 6), A(0)), A(1)), A(2)), A(3)), A(4)); }

On 32-bit Windows, the IR looks something like this:

  %1 = alloca inalloca <{ i32, %struct.A }>, align 4
  %2 = getelementptr inbounds <{ i32, %struct.A }>, <{ i32, %struct.A }>* %1, i32 0, i32 1
  %3 = call x86_thiscallcc %struct.A* @"??0A@@QAE at H@Z"(%struct.A* nonnull %2, i32 4)
  %4 = alloca inalloca <{ i32, %struct.A }>, align 4
  %5 = getelementptr inbounds <{ i32, %struct.A }>, <{ i32, %struct.A }>* %4, i32 0, i32 1
  %6 = call x86_thiscallcc %struct.A* @"??0A@@QAE at H@Z"(%struct.A* nonnull %5, i32 3)
  %7 = alloca inalloca <{ i32, %struct.A }>, align 4
  %8 = getelementptr inbounds <{ i32, %struct.A }>, <{ i32, %struct.A }>* %7, i32 0, i32 1
  %9 = call x86_thiscallcc %struct.A* @"??0A@@QAE at H@Z"(%struct.A* nonnull %8, i32 2)
  %10 = alloca inalloca <{ i32, %struct.A }>, align 4
  %11 = getelementptr inbounds <{ i32, %struct.A }>, <{ i32, %struct.A }>* %10, i32 0, i32 1
  %12 = call x86_thiscallcc %struct.A* @"??0A@@QAE at H@Z"(%struct.A* nonnull %11, i32 1)
  %13 = alloca inalloca <{ i32, %struct.A }>, align 4
  %14 = getelementptr inbounds <{ i32, %struct.A }>, <{ i32, %struct.A }>* %13, i32 0, i32 1
  %15 = call x86_thiscallcc %struct.A* @"??0A@@QAE at H@Z"(%struct.A* nonnull %14, i32 0)
  call void @"?sum@@YAXXZ"()
  call void @abort() #5
  unreachable

Notice the repeated alloca/gep/call pattern.  In the new world, the "alloca" will be replaced with preallocated.setup/preallocated.arg.  Now say your reroller decides to reroll that.  What's the result of "sum()"?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74651/new/

https://reviews.llvm.org/D74651





More information about the llvm-commits mailing list