Skip to content

Commit baaeb36

Browse files
committed
[AggressiveInstCombine] Implement memchr inlining optimization
This patch implements an optimization to inline small memchr calls into a sequence of loads and comparisons when the length is below a threshold. This allows better optimization of small string searches. The implementation: Adds support for inlining memchr calls with constant length, introduces a memchr-inline-threshold parameter (default: 6), and adds test coverage for small memchr operations.
1 parent 60540c8 commit baaeb36

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

AggressiveInstCombine.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
static bool foldMemChr(CallInst *Call, DomTreeUpdater *DTU,
2+
const DataLayout &DL) {
3+
Value *Ptr = Call->getArgOperand(0);
4+
Value *Val = Call->getArgOperand(1);
5+
Value *Len = Call->getArgOperand(2);
6+
7+
// If length is not a constant, we can't do the optimization
8+
auto *LenC = dyn_cast<ConstantInt>(Len);
9+
if (!LenC)
10+
return false;
11+
12+
uint64_t Length = LenC->getZExtValue();
13+
14+
// Check if this is a small memchr we should inline
15+
if (Length <= MemChrInlineThreshold) {
16+
IRBuilder<> IRB(Call);
17+
18+
// Truncate the search value to i8
19+
Value *ByteVal = IRB.CreateTrunc(Val, IRB.getInt8Ty());
20+
21+
// Initialize result to null
22+
Value *Result = ConstantPointerNull::get(cast<PointerType>(Call->getType()));
23+
24+
// For each byte up to Length
25+
for (unsigned i = 0; i < Length; i++) {
26+
Value *CurPtr = i == 0 ? Ptr :
27+
IRB.CreateGEP(IRB.getInt8Ty(), Ptr,
28+
ConstantInt::get(DL.getIndexType(Call->getType()), i));
29+
Value *CurByte = IRB.CreateLoad(IRB.getInt8Ty(), CurPtr);
30+
Value *CmpRes = IRB.CreateICmpEQ(CurByte, ByteVal);
31+
Result = IRB.CreateSelect(CmpRes, CurPtr, Result);
32+
}
33+
34+
// Replace the call with our expanded version
35+
Call->replaceAllUsesWith(Result);
36+
Call->eraseFromParent();
37+
return true;
38+
}
39+
40+
return false;
41+
}
42+
43+
// ... rest of the file unchanged ...

0 commit comments

Comments
 (0)