[PATCH] D38606: [CodeGen] Emit a helper function for __builtin_os_log_format to reduce code size

Akira Hatanaka via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 5 16:00:07 PDT 2017


ahatanak created this revision.

We found that the IR IRGen emits when expanding __builtin_os_log_format is quite big and has a lot of redundancy.

For example, when clang compiles the following code:

  void foo1(void *buf) {
    __builtin_os_log_format(buf, "%d %d", 11, 22);
  }

The IR looks like this:

  define void @foo1(i8* %buf) #0 {
  entry:
    %buf.addr = alloca i8*, align 8
    store i8* %buf, i8** %buf.addr, align 8
    %0 = load i8*, i8** %buf.addr, align 8
    %summary = getelementptr i8, i8* %0, i64 0
    store i8 0, i8* %summary, align 1
    %numArgs = getelementptr i8, i8* %0, i64 1
    store i8 2, i8* %numArgs, align 1
    %argDescriptor = getelementptr i8, i8* %0, i64 2
    store i8 0, i8* %argDescriptor, align 1
    %argSize = getelementptr i8, i8* %0, i64 3
    store i8 4, i8* %argSize, align 1
    %1 = getelementptr i8, i8* %0, i64 4
    %2 = bitcast i8* %1 to i32*
    store i32 11, i32* %2, align 1
    %argDescriptor1 = getelementptr i8, i8* %0, i64 8
    store i8 0, i8* %argDescriptor1, align 1
    %argSize2 = getelementptr i8, i8* %0, i64 9
    store i8 4, i8* %argSize2, align 1
    %3 = getelementptr i8, i8* %0, i64 10
    %4 = bitcast i8* %3 to i32*
    store i32 22, i32* %4, align 1
    ret void
  }

The IR generated when compiling a similar call like "__builtin_os_log_format(buf, "%d %d", 33, 44)" is almost the same except for the values of the integer constants stored, so there is an opportunity for code reductionton here.

To reduce code size, this patch modifies IRGen to emit a helper function that can be used by different call sites that call __builtin_os_log_format in a program. When compiling with -Oz, the generated helper function is marked as linkonce_odr, hidden, and noinline so that the linker can merge identical helper functions from different translation units. When compiling with other optimization levels, the function is marked as 'internal' and the generated IR should look mostly the same after inlining.

This patch also fixes a bug where the generated IR writes past the buffer when %m is the last directive. For example, the size of 'buf' in the following code is 4 but IRGen emits a store that writes a 4-byte value at buf+4.

  char buf[__builtin_os_log_format_buffer_size("%m")];
  __builtin_os_log_format(buf, "%m");

Original patch was written by Duncan.

rdar://problem/34065973
dar://problem/34196543


https://reviews.llvm.org/D38606

Files:
  lib/CodeGen/CGBuiltin.cpp
  lib/CodeGen/CodeGenFunction.h
  test/CodeGen/builtins.c
  test/CodeGenObjC/os_log.m

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D38606.117910.patch
Type: text/x-patch
Size: 48052 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20171005/0414839d/attachment-0001.bin>


More information about the cfe-commits mailing list