aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2008-04-23 18:34:37 +0000
committerDale Johannesen <dalej@apple.com>2008-04-23 18:34:37 +0000
commit1f530a59f72a95b1c11d5c0e9c33f8b77c8a12f2 (patch)
tree44c53615b50212b3b1b579f4dd09205d031b3aab
parentb013f5094c3bdb36472da996d63d5c0f75b6d4d3 (diff)
Rewrite previous patch to suit Chris's preference.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50174 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp52
1 files changed, 31 insertions, 21 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index c2f4545e4b..f51f02da67 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -8694,6 +8694,31 @@ Instruction *InstCombiner::visitInvokeInst(InvokeInst &II) {
return visitCallSite(&II);
}
+// If this cast does not affect the value passed through the varargs
+// area, we can eliminate the use of the cast.
+static bool isSafeToEliminateVarargsCast(const CallSite CS,
+ const CastInst * const CI,
+ const TargetData * const TD,
+ const int ix) {
+ if (!CI->isLosslessCast())
+ return false;
+
+ // The size of ByVal arguments is derived from the type, so we
+ // can't change to a type with a different size. If the size were
+ // passed explicitly we could avoid this check.
+ if (!CS.paramHasAttr(ix, ParamAttr::ByVal))
+ return true;
+
+ const Type* SrcTy =
+ cast<PointerType>(CI->getOperand(0)->getType())->getElementType();
+ const Type* DstTy = cast<PointerType>(CI->getType())->getElementType();
+ if (!SrcTy->isSized() || !DstTy->isSized())
+ return false;
+ if (TD->getABITypeSize(SrcTy) != TD->getABITypeSize(DstTy))
+ return false;
+ return true;
+}
+
// visitCallSite - Improvements for call and invoke instructions.
//
Instruction *InstCombiner::visitCallSite(CallSite CS) {
@@ -8752,28 +8777,13 @@ Instruction *InstCombiner::visitCallSite(CallSite CS) {
// See if we can optimize any arguments passed through the varargs area of
// the call.
for (CallSite::arg_iterator I = CS.arg_begin()+FTy->getNumParams(),
- E = CS.arg_end(); I != E; ++I, ++ix)
- if (CastInst *CI = dyn_cast<CastInst>(*I)) {
- // If this cast does not affect the value passed through the varargs
- // area, we can eliminate the use of the cast.
- const PointerType* SrcPTy, *DstPTy;
- if (CI->isLosslessCast()) {
- // The size of ByVal arguments is derived from the type, so we
- // can't change to a type with a different size. If the size were
- // passed explicitly we could avoid this check.
- if (CS.paramHasAttr(ix, ParamAttr::ByVal) &&
- (SrcPTy = cast<PointerType>(CI->getOperand(0)->getType())) &&
- (DstPTy = cast<PointerType>(CI->getType()))) {
- const Type* SrcTy = SrcPTy->getElementType();
- const Type* DstTy = DstPTy->getElementType();
- if (!SrcTy->isSized() || !DstTy->isSized() ||
- TD->getABITypeSize(SrcTy) != TD->getABITypeSize(DstTy))
- continue;
- }
- *I = CI->getOperand(0);
- Changed = true;
- }
+ E = CS.arg_end(); I != E; ++I, ++ix) {
+ CastInst *CI = dyn_cast<CastInst>(*I);
+ if (CI && isSafeToEliminateVarargsCast(CS, CI, TD, ix)) {
+ *I = CI->getOperand(0);
+ Changed = true;
}
+ }
}
if (isa<InlineAsm>(Callee) && !CS.doesNotThrow()) {