llvm.org GIT mirror llvm / 09c11aa
clean up strcat optimizer, no functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35704 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 12 years ago
1 changed file(s) with 23 addition(s) and 30 deletion(s). Raw diff Collapse all Expand all
473473 }
474474
475475 /// @brief Optimize the strcat library function
476 virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC) {
476 virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
477477 // Extract some information from the instruction
478 Value* dest = ci->getOperand(1);
479 Value* src = ci->getOperand(2);
478 Value *Dst = CI->getOperand(1);
479 Value *Src = CI->getOperand(2);
480480
481481 // Extract the initializer (while making numerous checks) from the
482 // source operand of the call to strcat. If we get null back, one of
483 // a variety of checks in get_GVInitializer failed
484 uint64_t len, StartIdx;
482 // source operand of the call to strcat.
483 uint64_t SrcLength, StartIdx;
485484 ConstantArray *Arr;
486 if (!GetConstantStringInfo(src, Arr, len, StartIdx))
485 if (!GetConstantStringInfo(Src, Arr, SrcLength, StartIdx))
487486 return false;
488487
489488 // Handle the simple, do-nothing case
490 if (len == 0) {
491 ci->replaceAllUsesWith(dest);
492 ci->eraseFromParent();
493 return true;
494 }
495
496 // Increment the length because we actually want to memcpy the null
497 // terminator as well.
498 len++;
489 if (SrcLength == 0) {
490 CI->replaceAllUsesWith(Dst);
491 CI->eraseFromParent();
492 return true;
493 }
499494
500495 // We need to find the end of the destination string. That's where the
501496 // memory is to be moved to. We just generate a call to strlen (further
502 // optimized in another pass). Note that the SLC.get_strlen() call
503 // caches the Function* for us.
504 CallInst* strlen_inst =
505 new CallInst(SLC.get_strlen(), dest, dest->getName()+".len",ci);
497 // optimized in another pass).
498 CallInst *DstLen = new CallInst(SLC.get_strlen(), Dst,
499 Dst->getName()+".len", CI);
506500
507501 // Now that we have the destination's length, we must index into the
508502 // destination's pointer to get the actual memcpy destination (end of
509503 // the string .. we're concatenating).
510 GetElementPtrInst* gep =
511 new GetElementPtrInst(dest, strlen_inst, dest->getName()+".indexed", ci);
504 Dst = new GetElementPtrInst(Dst, DstLen, Dst->getName()+".indexed", CI);
512505
513506 // We have enough information to now generate the memcpy call to
514507 // do the concatenation for us.
515 Value *vals[4];
516 vals[0] = gep; // destination
517 vals[1] = ci->getOperand(2); // source
518 vals[2] = ConstantInt::get(SLC.getIntPtrType(),len); // length
519 vals[3] = ConstantInt::get(Type::Int32Ty,1); // alignment
520 new CallInst(SLC.get_memcpy(), vals, 4, "", ci);
508 Value *Vals[] = {
509 Dst, Src,
510 ConstantInt::get(SLC.getIntPtrType(), SrcLength+1), // copy nul term.
511 ConstantInt::get(Type::Int32Ty, 1) // alignment
512 };
513 new CallInst(SLC.get_memcpy(), Vals, 4, "", CI);
521514
522515 // Finally, substitute the first operand of the strcat call for the
523516 // strcat call itself since strcat returns its first operand; and,
524517 // kill the strcat CallInst.
525 ci->replaceAllUsesWith(dest);
526 ci->eraseFromParent();
518 CI->replaceAllUsesWith(Dst);
519 CI->eraseFromParent();
527520 return true;
528521 }
529522 } StrCatOptimizer;