Q:

Why didn't GCC optimize this 'printf' to 'puts'?

Here is my test code:
#include<stdio.h>

static inline void foo(int a){
    printf("%x\n", a);  
}

int main(void){
    foo(0x1234);    
    return 0;
}

I thought GCC should realize that a is a literal integer, and optimize to code like this:
puts("1234");

But I got the following assembly code:
│0x8048341 <main+17>     push   $0x1234                                        
│0x8048346 <main+22>     push   $0x80484e0                                  
│0x804834b <main+27>     push   $0x1                                        
│0x804834d <main+29>     call   0x8048310 <__printf_chk@plt> 

There exists a lot of such code in my project, because I always believed that GCC would optimize for me, and even in some context where could simply use 'write()', I insisted using printf, because I thought I would gain benefit from its buffer mechanism.
Now I feel regret, for the overhead of paring a format string will kill any gain I have. These codes in my project are quite low-level, and they might cause the performance bottleneck.

A:

These codes in my project are quite low-level, and they might cause the performance bottleneck.

First off, I can assuage your fears that this is not possible. The overhead of console I/O is tremendous (relatively speaking), so that will always be the bottleneck in your code, no matter what means you use to do it.

I thought gcc should realize that a is a literal integer, and optimize to code like this:
puts("1234");

Clearly it doesn't. GCC (and Clang) does perform an optimization where printf("...\n"); is transformed into puts("...");, as you can see here, but this only happens when you use string literals with printf. The optimizer doesn't (currently) peek into the format string, parse it, and optimize around it. You called printf, so you get printf.
Compiler optimizations aren't guaranteed, so you shouldn't write code that relies on them without first verifying that the desired optimizations are in fact being applied under all circumstances in which you are interested (including code variations, compiler versions, target platforms, etc.).
If you'd like to suggest this as a possible improvement for the GCC optimizer, you can suggest an enhancement on their Bugzilla. But don't hold your breath on it being implemented any time soon. The logic required to implement this type of optimization is not really worth the effort, considering the real-world performance improvements that could be expected are minimal at best (see above).
In the meantime, if you absolutely require this optimization with minimal changes to your code, then you can use some macro hackery:
#define STRINGIFY_INTERNAL(x)  #x
#define STRINGIFY(x)           STRINGIFY_INTERNAL(x)

#define foo(a)                 puts(STRINGIFY(a))

This does produce the desired output:
.LC0:
        .string "0x1234"
MyFunction:
        sub     esp, 24
        push    OFFSET FLAT:.LC0
        call    puts
        xor     eax, eax
        add     esp, 28
        ret

