LLVM middle-end 최적화 관련 주의점(?)
1. 당면한 문제에 `몰입`도 중요하지만 더 큰 구조를 생각하는 것도 중요하다.
제가 경험했던 패치
https://reviews.llvm.org/D153752
⚙ D153752 [InstSimplify] Fold icmp comparing GEPs with local allocation
This revision is now accepted and ready to land.
reviews.llvm.org
최근에 살펴본 패치
https://die4taoam.tistory.com/136
[InstSimplify] Fold (a != 0) ? abs(a) : 0
https://github.com/llvm/llvm-project/pull/70305 [InstSimplify] Fold (a != 0) ? abs(a) : 0 by Pierre-vh · Pull Request #70305 · llvm/llvm-project Solves #70204 github.com 문제가 발생하는 경우를 추적해 봅시다. # cat pp.c int f(int a) { if (
die4taoam.tistory.com
이슈를 패치하는 과정에서 '특정' 과정을 추가하는데 몰입되는 경향이 있을 수 있습니다. 위 패치의 경우는 `(a != 0) ? abs(a) : 0` 가 왔을 때 처리하는 별도의 로직을 추가하는 방향으로 최초 시도됩니다. 후에 리뷰에서와 같이 InstructionSimplify 에서 Instruction::abs 에 poison 되지 않는 경우를 예외처리 하는 것으로 패치가 완료되는 것을 확인 할 수 있습니다.
이 패치의 경우도 `memcpy의 인자가 왜 null 이야?` 라는 식으로 접근하면 문제가 이상하게 흘렀을 수 있다는 생각이 듭니다. `할당되지 않은 메모리에 대한 memcpy 최적화 시 에러가 발생한다.` 는 접근이 올바르게 문제를 해결하기 위한 첫 단계였습니다.
패치를 계속 리뷰하다보면 관련 지식이 쌓이고 지식이 쌓이면 직관이 생기지 않을까 합니다.
2. 만들고자 하는 최적화와 유관한 최적화가 이미 존재하는지 확인
다음의 경우,
https://github.com/llvm/llvm-project/pull/73990
[InstCombine] simplify `icmp pred x, ~x` by ParkHanbum · Pull Request #73990 · llvm/llvm-project
simplify compare between specific variable X and NOT(X) Proof: https://alive2.llvm.org/ce/z/KTCpjP Fixed #57532.
github.com
본문에 nikic 가 달아준 댓글처럼
일부 중첩되는 케이스가 존재하는 최적화가 이미 존재했다.
// icmp (X ^ Y_NonZero) u>= X --> icmp (X ^ Y_NonZero) u> X
// icmp (X ^ Y_NonZero) u<= X --> icmp (X ^ Y_NonZero) u< X
// icmp (X ^ Y_NonZero) s>= X --> icmp (X ^ Y_NonZero) s> X
// icmp (X ^ Y_NonZero) s<= X --> icmp (X ^ Y_NonZero) s< X
CmpInst::Predicate PredOut = CmpInst::getStrictPredicate(Pred);
if (PredOut != Pred &&
isKnownNonZero(A, Q.DL, /*Depth=*/0, Q.AC, Q.CxtI, Q.DT))
return new ICmpInst(PredOut, Op0, Op1);
return nullptr;
}
그러므로 최적화를 만들고자 할 때,
테스트케이스를 만들고 해당 테스트케이스가 기존의 코드에서 어떻게 변화되는지 여부를 먼저 확인하는게 좋다.