[CIR] Match OGCG's epilogue codegen
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
Currently the original LLVMIR codegen for a simple C++ source program:
```c
int test(int a, int b) { return (a - 1) + b; }
```
is
```llvm
...
define i32 @test(i32 noundef %a, i32 noundef %b) #0 {
entry:
%a.addr = alloca i32, align 4
%b.addr = alloca i32, align 4
store i32 %a, ptr %a.addr, align 4
store i32 %b, ptr %b.addr, align 4
%0 = load i32, ptr %a.addr, align 4
%sub = sub nsw i32 %0, 1
%1 = load i32, ptr %b.addr, align 4
%add = add nsw i32 %sub, %1
ret i32 %add
}
...
}
```
However, currently in the lowering from CIR to LLVMIR we get:
```llvm
...
define i32 @test(i32 %0, i32 %1) #0 {
%3 = alloca i32, i64 1, align 4
%4 = alloca i32, i64 1, align 4
%5 = alloca i32, i64 1, align 4
store i32 %0, ptr %3, align 4
store i32 %1, ptr %4, align 4
%6 = load i32, ptr %3, align 4
%7 = sub nsw i32 %6, 1
%8 = load i32, ptr %4, align 4
%9 = add nsw i32 %7, %8
store i32 %9, ptr %5, align 4
%10 = load i32, ptr %5, align 4
ret i32 %10
}
...
```
Basically we have a superfluous store-load pair and an extra alloca for the variable stored into in the LLVMIR lowered from CIR.
In the OGCG these pair are elided see: https://github.com/llvm/llvm-project/blob/48f53422fe7f627fcdace90bd7c3c5ee056bc0a6/clang/lib/CodeGen/CGCall.cpp#L4090-L4106. This is possible because we have [AbIArgInfo](https://github.com/llvm/llvm-project/blob/cd47ae9f8ff9afa46209806e94bfadb0056049c5/clang/include/clang/CodeGen/CGFunctionInfo.h#L32) as part of [CGFunctionInfo](https://github.com/llvm/llvm-project/blob/cd47ae9f8ff9afa46209806e94bfadb0056049c5/clang/include/clang/CodeGen/CGFunctionInfo.h#L596).
This allow us to know if this a direct return or the value will be returned indirectly in an output parameter or it's an "InAlloca"...etc
In the even of a direct return where the return value is dominated by the store to the return value, we can safely elide and delete the store operation.
So looks to me like we need to have this information at the CIR level to be able to pass it down and utilise it when we are doing the lowering to LLVMIR.
Contributor guide
Research direction
Start by reading the cited return handling in clang/lib/CodeGen/CGCall.cpp and the ABI structures in clang/include/clang/CodeGen/CGFunctionInfo.h. Then trace how CIR lowering represents return values and passes that information to LLVM IR. Done means the sample direct-return function no longer has the extra return alloca or store-load pair.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Refactor
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100