summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/CodeGen/Analysis.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2014-03-21 17:53:59 +0000
committerdim <dim@FreeBSD.org>2014-03-21 17:53:59 +0000
commit9cedb8bb69b89b0f0c529937247a6a80cabdbaec (patch)
treec978f0e9ec1ab92dc8123783f30b08a7fd1e2a39 /contrib/llvm/lib/CodeGen/Analysis.cpp
parent03fdc2934eb61c44c049a02b02aa974cfdd8a0eb (diff)
downloadFreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.zip
FreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.tar.gz
MFC 261991:
Upgrade our copy of llvm/clang to 3.4 release. This version supports all of the features in the current working draft of the upcoming C++ standard, provisionally named C++1y. The code generator's performance is greatly increased, and the loop auto-vectorizer is now enabled at -Os and -O2 in addition to -O3. The PowerPC backend has made several major improvements to code generation quality and compile time, and the X86, SPARC, ARM32, Aarch64 and SystemZ backends have all seen major feature work. Release notes for llvm and clang can be found here: <http://llvm.org/releases/3.4/docs/ReleaseNotes.html> <http://llvm.org/releases/3.4/tools/clang/docs/ReleaseNotes.html> MFC 262121 (by emaste): Update lldb for clang/llvm 3.4 import This commit largely restores the lldb source to the upstream r196259 snapshot with the addition of threaded inferior support and a few bug fixes. Specific upstream lldb revisions restored include: SVN git 181387 779e6ac 181703 7bef4e2 182099 b31044e 182650 f2dcf35 182683 0d91b80 183862 15c1774 183929 99447a6 184177 0b2934b 184948 4dc3761 184954 007e7bc 186990 eebd175 Sponsored by: DARPA, AFRL MFC 262186 (by emaste): Fix mismerge in r262121 A break statement was lost in the merge. The error had no functional impact, but restore it to reduce the diff against upstream. MFC 262303: Pull in r197521 from upstream clang trunk (by rdivacky): Use the integrated assembler by default on FreeBSD/ppc and ppc64. Requested by: jhibbits MFC 262611: Pull in r196874 from upstream llvm trunk: Fix a crash that occurs when PWD is invalid. MCJIT needs to be able to run in hostile environments, even when PWD is invalid. There's no need to crash MCJIT in this case. The obvious fix is to simply leave MCContext's CompilationDir empty when PWD can't be determined. This way, MCJIT clients, and other clients that link with LLVM don't need a valid working directory. If we do want to guarantee valid CompilationDir, that should be done only for clients of getCompilationDir(). This is as simple as checking for an empty string. The only current use of getCompilationDir is EmitGenDwarfInfo, which won't conceivably run with an invalid working dir. However, in the purely hypothetically and untestable case that this happens, the AT_comp_dir will be omitted from the compilation_unit DIE. This should help fix assertions occurring with ports-mgmt/tinderbox, when it is using jails, and sometimes invalidates clang's current working directory. Reported by: decke MFC 262809: Pull in r203007 from upstream clang trunk: Don't produce an alias between destructors with different calling conventions. Fixes pr19007. (Please note that is an LLVM PR identifier, not a FreeBSD one.) This should fix Firefox and/or libxul crashes (due to problems with regparm/stdcall calling conventions) on i386. Reported by: multiple users on freebsd-current PR: bin/187103 MFC 263048: Repair recognition of "CC" as an alias for the C++ compiler, since it was silently broken by upstream for a Windows-specific use-case. Apparently some versions of CMake still rely on this archaic feature... Reported by: rakuco MFC 263049: Garbage collect the old way of adding the libstdc++ include directories in clang's InitHeaderSearch.cpp. This has been superseded by David Chisnall's commit in r255321. Moreover, if libc++ is used, the libstdc++ include directories should not be in the search path at all. These directories are now only used if you pass -stdlib=libstdc++.
Diffstat (limited to 'contrib/llvm/lib/CodeGen/Analysis.cpp')
-rw-r--r--contrib/llvm/lib/CodeGen/Analysis.cpp475
1 files changed, 328 insertions, 147 deletions
diff --git a/contrib/llvm/lib/CodeGen/Analysis.cpp b/contrib/llvm/lib/CodeGen/Analysis.cpp
index 4731af5..1600c67 100644
--- a/contrib/llvm/lib/CodeGen/Analysis.cpp
+++ b/contrib/llvm/lib/CodeGen/Analysis.cpp
@@ -202,161 +202,272 @@ ISD::CondCode llvm::getICmpCondCode(ICmpInst::Predicate Pred) {
}
static bool isNoopBitcast(Type *T1, Type *T2,
- const TargetLowering& TLI) {
+ const TargetLoweringBase& TLI) {
return T1 == T2 || (T1->isPointerTy() && T2->isPointerTy()) ||
(isa<VectorType>(T1) && isa<VectorType>(T2) &&
TLI.isTypeLegal(EVT::getEVT(T1)) && TLI.isTypeLegal(EVT::getEVT(T2)));
}
-/// sameNoopInput - Return true if V1 == V2, else if either V1 or V2 is a noop
-/// (i.e., lowers to no machine code), look through it (and any transitive noop
-/// operands to it) and check if it has the same noop input value. This is
-/// used to determine if a tail call can be formed.
-static bool sameNoopInput(const Value *V1, const Value *V2,
- SmallVectorImpl<unsigned> &Els1,
- SmallVectorImpl<unsigned> &Els2,
- const TargetLowering &TLI) {
- using std::swap;
- bool swapParity = false;
- bool equalEls = Els1 == Els2;
+/// Look through operations that will be free to find the earliest source of
+/// this value.
+///
+/// @param ValLoc If V has aggegate type, we will be interested in a particular
+/// scalar component. This records its address; the reverse of this list gives a
+/// sequence of indices appropriate for an extractvalue to locate the important
+/// value. This value is updated during the function and on exit will indicate
+/// similar information for the Value returned.
+///
+/// @param DataBits If this function looks through truncate instructions, this
+/// will record the smallest size attained.
+static const Value *getNoopInput(const Value *V,
+ SmallVectorImpl<unsigned> &ValLoc,
+ unsigned &DataBits,
+ const TargetLoweringBase &TLI) {
while (true) {
- if ((equalEls && V1 == V2) || isa<UndefValue>(V1) || isa<UndefValue>(V2)) {
- if (swapParity)
- // Revert to original Els1 and Els2 to avoid confusing recursive calls
- swap(Els1, Els2);
- return true;
- }
-
// Try to look through V1; if V1 is not an instruction, it can't be looked
// through.
- const Instruction *I = dyn_cast<Instruction>(V1);
+ const Instruction *I = dyn_cast<Instruction>(V);
+ if (!I || I->getNumOperands() == 0) return V;
const Value *NoopInput = 0;
- if (I != 0 && I->getNumOperands() > 0) {
- Value *Op = I->getOperand(0);
- if (isa<TruncInst>(I)) {
- // Look through truly no-op truncates.
- if (TLI.isTruncateFree(Op->getType(), I->getType()))
- NoopInput = Op;
- } else if (isa<BitCastInst>(I)) {
- // Look through truly no-op bitcasts.
- if (isNoopBitcast(Op->getType(), I->getType(), TLI))
- NoopInput = Op;
- } else if (isa<GetElementPtrInst>(I)) {
- // Look through getelementptr
- if (cast<GetElementPtrInst>(I)->hasAllZeroIndices())
- NoopInput = Op;
- } else if (isa<IntToPtrInst>(I)) {
- // Look through inttoptr.
- // Make sure this isn't a truncating or extending cast. We could
- // support this eventually, but don't bother for now.
- if (!isa<VectorType>(I->getType()) &&
- TLI.getPointerTy().getSizeInBits() ==
- cast<IntegerType>(Op->getType())->getBitWidth())
- NoopInput = Op;
- } else if (isa<PtrToIntInst>(I)) {
- // Look through ptrtoint.
- // Make sure this isn't a truncating or extending cast. We could
- // support this eventually, but don't bother for now.
- if (!isa<VectorType>(I->getType()) &&
- TLI.getPointerTy().getSizeInBits() ==
- cast<IntegerType>(I->getType())->getBitWidth())
- NoopInput = Op;
- } else if (isa<CallInst>(I)) {
- // Look through call
- for (User::const_op_iterator i = I->op_begin(),
- // Skip Callee
- e = I->op_end() - 1;
- i != e; ++i) {
- unsigned attrInd = i - I->op_begin() + 1;
- if (cast<CallInst>(I)->paramHasAttr(attrInd, Attribute::Returned) &&
- isNoopBitcast((*i)->getType(), I->getType(), TLI)) {
- NoopInput = *i;
- break;
- }
+
+ Value *Op = I->getOperand(0);
+ if (isa<BitCastInst>(I)) {
+ // Look through truly no-op bitcasts.
+ if (isNoopBitcast(Op->getType(), I->getType(), TLI))
+ NoopInput = Op;
+ } else if (isa<GetElementPtrInst>(I)) {
+ // Look through getelementptr
+ if (cast<GetElementPtrInst>(I)->hasAllZeroIndices())
+ NoopInput = Op;
+ } else if (isa<IntToPtrInst>(I)) {
+ // Look through inttoptr.
+ // Make sure this isn't a truncating or extending cast. We could
+ // support this eventually, but don't bother for now.
+ if (!isa<VectorType>(I->getType()) &&
+ TLI.getPointerTy().getSizeInBits() ==
+ cast<IntegerType>(Op->getType())->getBitWidth())
+ NoopInput = Op;
+ } else if (isa<PtrToIntInst>(I)) {
+ // Look through ptrtoint.
+ // Make sure this isn't a truncating or extending cast. We could
+ // support this eventually, but don't bother for now.
+ if (!isa<VectorType>(I->getType()) &&
+ TLI.getPointerTy().getSizeInBits() ==
+ cast<IntegerType>(I->getType())->getBitWidth())
+ NoopInput = Op;
+ } else if (isa<TruncInst>(I) &&
+ TLI.allowTruncateForTailCall(Op->getType(), I->getType())) {
+ DataBits = std::min(DataBits, I->getType()->getPrimitiveSizeInBits());
+ NoopInput = Op;
+ } else if (isa<CallInst>(I)) {
+ // Look through call (skipping callee)
+ for (User::const_op_iterator i = I->op_begin(), e = I->op_end() - 1;
+ i != e; ++i) {
+ unsigned attrInd = i - I->op_begin() + 1;
+ if (cast<CallInst>(I)->paramHasAttr(attrInd, Attribute::Returned) &&
+ isNoopBitcast((*i)->getType(), I->getType(), TLI)) {
+ NoopInput = *i;
+ break;
}
- } else if (isa<InvokeInst>(I)) {
- // Look through invoke
- for (User::const_op_iterator i = I->op_begin(),
- // Skip BB, BB, Callee
- e = I->op_end() - 3;
- i != e; ++i) {
- unsigned attrInd = i - I->op_begin() + 1;
- if (cast<InvokeInst>(I)->paramHasAttr(attrInd, Attribute::Returned) &&
- isNoopBitcast((*i)->getType(), I->getType(), TLI)) {
- NoopInput = *i;
- break;
- }
+ }
+ } else if (isa<InvokeInst>(I)) {
+ // Look through invoke (skipping BB, BB, Callee)
+ for (User::const_op_iterator i = I->op_begin(), e = I->op_end() - 3;
+ i != e; ++i) {
+ unsigned attrInd = i - I->op_begin() + 1;
+ if (cast<InvokeInst>(I)->paramHasAttr(attrInd, Attribute::Returned) &&
+ isNoopBitcast((*i)->getType(), I->getType(), TLI)) {
+ NoopInput = *i;
+ break;
}
}
+ } else if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(V)) {
+ // Value may come from either the aggregate or the scalar
+ ArrayRef<unsigned> InsertLoc = IVI->getIndices();
+ if (std::equal(InsertLoc.rbegin(), InsertLoc.rend(),
+ ValLoc.rbegin())) {
+ // The type being inserted is a nested sub-type of the aggregate; we
+ // have to remove those initial indices to get the location we're
+ // interested in for the operand.
+ ValLoc.resize(ValLoc.size() - InsertLoc.size());
+ NoopInput = IVI->getInsertedValueOperand();
+ } else {
+ // The struct we're inserting into has the value we're interested in, no
+ // change of address.
+ NoopInput = Op;
+ }
+ } else if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(V)) {
+ // The part we're interested in will inevitably be some sub-section of the
+ // previous aggregate. Combine the two paths to obtain the true address of
+ // our element.
+ ArrayRef<unsigned> ExtractLoc = EVI->getIndices();
+ std::copy(ExtractLoc.rbegin(), ExtractLoc.rend(),
+ std::back_inserter(ValLoc));
+ NoopInput = Op;
}
+ // Terminate if we couldn't find anything to look through.
+ if (!NoopInput)
+ return V;
- if (NoopInput) {
- V1 = NoopInput;
- continue;
- }
+ V = NoopInput;
+ }
+}
+
+/// Return true if this scalar return value only has bits discarded on its path
+/// from the "tail call" to the "ret". This includes the obvious noop
+/// instructions handled by getNoopInput above as well as free truncations (or
+/// extensions prior to the call).
+static bool slotOnlyDiscardsData(const Value *RetVal, const Value *CallVal,
+ SmallVectorImpl<unsigned> &RetIndices,
+ SmallVectorImpl<unsigned> &CallIndices,
+ bool AllowDifferingSizes,
+ const TargetLoweringBase &TLI) {
+
+ // Trace the sub-value needed by the return value as far back up the graph as
+ // possible, in the hope that it will intersect with the value produced by the
+ // call. In the simple case with no "returned" attribute, the hope is actually
+ // that we end up back at the tail call instruction itself.
+ unsigned BitsRequired = UINT_MAX;
+ RetVal = getNoopInput(RetVal, RetIndices, BitsRequired, TLI);
+
+ // If this slot in the value returned is undef, it doesn't matter what the
+ // call puts there, it'll be fine.
+ if (isa<UndefValue>(RetVal))
+ return true;
- // If we already swapped, avoid infinite loop
- if (swapParity)
- break;
+ // Now do a similar search up through the graph to find where the value
+ // actually returned by the "tail call" comes from. In the simple case without
+ // a "returned" attribute, the search will be blocked immediately and the loop
+ // a Noop.
+ unsigned BitsProvided = UINT_MAX;
+ CallVal = getNoopInput(CallVal, CallIndices, BitsProvided, TLI);
+
+ // There's no hope if we can't actually trace them to (the same part of!) the
+ // same value.
+ if (CallVal != RetVal || CallIndices != RetIndices)
+ return false;
+
+ // However, intervening truncates may have made the call non-tail. Make sure
+ // all the bits that are needed by the "ret" have been provided by the "tail
+ // call". FIXME: with sufficiently cunning bit-tracking, we could look through
+ // extensions too.
+ if (BitsProvided < BitsRequired ||
+ (!AllowDifferingSizes && BitsProvided != BitsRequired))
+ return false;
- // Otherwise, swap V1<->V2, Els1<->Els2
- swap(V1, V2);
- swap(Els1, Els2);
- swapParity = !swapParity;
+ return true;
+}
+
+/// For an aggregate type, determine whether a given index is within bounds or
+/// not.
+static bool indexReallyValid(CompositeType *T, unsigned Idx) {
+ if (ArrayType *AT = dyn_cast<ArrayType>(T))
+ return Idx < AT->getNumElements();
+
+ return Idx < cast<StructType>(T)->getNumElements();
+}
+
+/// Move the given iterators to the next leaf type in depth first traversal.
+///
+/// Performs a depth-first traversal of the type as specified by its arguments,
+/// stopping at the next leaf node (which may be a legitimate scalar type or an
+/// empty struct or array).
+///
+/// @param SubTypes List of the partial components making up the type from
+/// outermost to innermost non-empty aggregate. The element currently
+/// represented is SubTypes.back()->getTypeAtIndex(Path.back() - 1).
+///
+/// @param Path Set of extractvalue indices leading from the outermost type
+/// (SubTypes[0]) to the leaf node currently represented.
+///
+/// @returns true if a new type was found, false otherwise. Calling this
+/// function again on a finished iterator will repeatedly return
+/// false. SubTypes.back()->getTypeAtIndex(Path.back()) is either an empty
+/// aggregate or a non-aggregate
+static bool advanceToNextLeafType(SmallVectorImpl<CompositeType *> &SubTypes,
+ SmallVectorImpl<unsigned> &Path) {
+ // First march back up the tree until we can successfully increment one of the
+ // coordinates in Path.
+ while (!Path.empty() && !indexReallyValid(SubTypes.back(), Path.back() + 1)) {
+ Path.pop_back();
+ SubTypes.pop_back();
}
- for (unsigned n = 0; n < 2; ++n) {
- if (isa<InsertValueInst>(V1)) {
- if (isa<StructType>(V1->getType())) {
- // Look through insertvalue
- unsigned i, e;
- for (i = 0, e = cast<StructType>(V1->getType())->getNumElements();
- i != e; ++i) {
- const Value *InScalar = FindInsertedValue(const_cast<Value*>(V1), i);
- if (InScalar == 0)
- break;
- Els1.push_back(i);
- if (!sameNoopInput(InScalar, V2, Els1, Els2, TLI)) {
- Els1.pop_back();
- break;
- }
- Els1.pop_back();
- }
- if (i == e) {
- if (swapParity)
- swap(Els1, Els2);
- return true;
- }
- }
- } else if (!Els1.empty() && isa<ExtractValueInst>(V1)) {
- const ExtractValueInst *EVI = cast<ExtractValueInst>(V1);
- unsigned i = Els1.back();
- // If the scalar value being inserted is an extractvalue of the right
- // index from the call, then everything is good.
- if (isa<StructType>(EVI->getOperand(0)->getType()) &&
- EVI->getNumIndices() == 1 && EVI->getIndices()[0] == i) {
- // Look through extractvalue
- Els1.pop_back();
- if (sameNoopInput(EVI->getOperand(0), V2, Els1, Els2, TLI)) {
- Els1.push_back(i);
- if (swapParity)
- swap(Els1, Els2);
- return true;
- }
- Els1.push_back(i);
- }
- }
+ // If we reached the top, then the iterator is done.
+ if (Path.empty())
+ return false;
- swap(V1, V2);
- swap(Els1, Els2);
- swapParity = !swapParity;
+ // We know there's *some* valid leaf now, so march back down the tree picking
+ // out the left-most element at each node.
+ ++Path.back();
+ Type *DeeperType = SubTypes.back()->getTypeAtIndex(Path.back());
+ while (DeeperType->isAggregateType()) {
+ CompositeType *CT = cast<CompositeType>(DeeperType);
+ if (!indexReallyValid(CT, 0))
+ return true;
+
+ SubTypes.push_back(CT);
+ Path.push_back(0);
+
+ DeeperType = CT->getTypeAtIndex(0U);
}
- if (swapParity)
- swap(Els1, Els2);
- return false;
+ return true;
}
+/// Find the first non-empty, scalar-like type in Next and setup the iterator
+/// components.
+///
+/// Assuming Next is an aggregate of some kind, this function will traverse the
+/// tree from left to right (i.e. depth-first) looking for the first
+/// non-aggregate type which will play a role in function return.
+///
+/// For example, if Next was {[0 x i64], {{}, i32, {}}, i32} then we would setup
+/// Path as [1, 1] and SubTypes as [Next, {{}, i32, {}}] to represent the first
+/// i32 in that type.
+static bool firstRealType(Type *Next,
+ SmallVectorImpl<CompositeType *> &SubTypes,
+ SmallVectorImpl<unsigned> &Path) {
+ // First initialise the iterator components to the first "leaf" node
+ // (i.e. node with no valid sub-type at any index, so {} does count as a leaf
+ // despite nominally being an aggregate).
+ while (Next->isAggregateType() &&
+ indexReallyValid(cast<CompositeType>(Next), 0)) {
+ SubTypes.push_back(cast<CompositeType>(Next));
+ Path.push_back(0);
+ Next = cast<CompositeType>(Next)->getTypeAtIndex(0U);
+ }
+
+ // If there's no Path now, Next was originally scalar already (or empty
+ // leaf). We're done.
+ if (Path.empty())
+ return true;
+
+ // Otherwise, use normal iteration to keep looking through the tree until we
+ // find a non-aggregate type.
+ while (SubTypes.back()->getTypeAtIndex(Path.back())->isAggregateType()) {
+ if (!advanceToNextLeafType(SubTypes, Path))
+ return false;
+ }
+
+ return true;
+}
+
+/// Set the iterator data-structures to the next non-empty, non-aggregate
+/// subtype.
+static bool nextRealType(SmallVectorImpl<CompositeType *> &SubTypes,
+ SmallVectorImpl<unsigned> &Path) {
+ do {
+ if (!advanceToNextLeafType(SubTypes, Path))
+ return false;
+
+ assert(!Path.empty() && "found a leaf but didn't set the path?");
+ } while (SubTypes.back()->getTypeAtIndex(Path.back())->isAggregateType());
+
+ return true;
+}
+
+
/// Test if the given instruction is in a position to be optimized
/// with a tail-call. This roughly means that it's in a block with
/// a return and there's nothing that needs to be scheduled
@@ -399,6 +510,13 @@ bool llvm::isInTailCallPosition(ImmutableCallSite CS,
return false;
}
+ return returnTypeIsEligibleForTailCall(ExitBB->getParent(), I, Ret, TLI);
+}
+
+bool llvm::returnTypeIsEligibleForTailCall(const Function *F,
+ const Instruction *I,
+ const ReturnInst *Ret,
+ const TargetLoweringBase &TLI) {
// If the block ends with a void return or unreachable, it doesn't matter
// what the call's return type is.
if (!Ret || Ret->getNumOperands() == 0) return true;
@@ -407,22 +525,85 @@ bool llvm::isInTailCallPosition(ImmutableCallSite CS,
// return type is.
if (isa<UndefValue>(Ret->getOperand(0))) return true;
- // Conservatively require the attributes of the call to match those of
- // the return. Ignore noalias because it doesn't affect the call sequence.
- const Function *F = ExitBB->getParent();
- AttributeSet CallerAttrs = F->getAttributes();
- if (AttrBuilder(CallerAttrs, AttributeSet::ReturnIndex).
- removeAttribute(Attribute::NoAlias) !=
- AttrBuilder(CallerAttrs, AttributeSet::ReturnIndex).
- removeAttribute(Attribute::NoAlias))
- return false;
+ // Make sure the attributes attached to each return are compatible.
+ AttrBuilder CallerAttrs(F->getAttributes(),
+ AttributeSet::ReturnIndex);
+ AttrBuilder CalleeAttrs(cast<CallInst>(I)->getAttributes(),
+ AttributeSet::ReturnIndex);
+
+ // Noalias is completely benign as far as calling convention goes, it
+ // shouldn't affect whether the call is a tail call.
+ CallerAttrs = CallerAttrs.removeAttribute(Attribute::NoAlias);
+ CalleeAttrs = CalleeAttrs.removeAttribute(Attribute::NoAlias);
+
+ bool AllowDifferingSizes = true;
+ if (CallerAttrs.contains(Attribute::ZExt)) {
+ if (!CalleeAttrs.contains(Attribute::ZExt))
+ return false;
- // It's not safe to eliminate the sign / zero extension of the return value.
- if (CallerAttrs.hasAttribute(AttributeSet::ReturnIndex, Attribute::ZExt) ||
- CallerAttrs.hasAttribute(AttributeSet::ReturnIndex, Attribute::SExt))
+ AllowDifferingSizes = false;
+ CallerAttrs.removeAttribute(Attribute::ZExt);
+ CalleeAttrs.removeAttribute(Attribute::ZExt);
+ } else if (CallerAttrs.contains(Attribute::SExt)) {
+ if (!CalleeAttrs.contains(Attribute::SExt))
+ return false;
+
+ AllowDifferingSizes = false;
+ CallerAttrs.removeAttribute(Attribute::SExt);
+ CalleeAttrs.removeAttribute(Attribute::SExt);
+ }
+
+ // If they're still different, there's some facet we don't understand
+ // (currently only "inreg", but in future who knows). It may be OK but the
+ // only safe option is to reject the tail call.
+ if (CallerAttrs != CalleeAttrs)
return false;
- // Otherwise, make sure the return value and I have the same value
- SmallVector<unsigned, 4> Els1, Els2;
- return sameNoopInput(Ret->getOperand(0), I, Els1, Els2, TLI);
+ const Value *RetVal = Ret->getOperand(0), *CallVal = I;
+ SmallVector<unsigned, 4> RetPath, CallPath;
+ SmallVector<CompositeType *, 4> RetSubTypes, CallSubTypes;
+
+ bool RetEmpty = !firstRealType(RetVal->getType(), RetSubTypes, RetPath);
+ bool CallEmpty = !firstRealType(CallVal->getType(), CallSubTypes, CallPath);
+
+ // Nothing's actually returned, it doesn't matter what the callee put there
+ // it's a valid tail call.
+ if (RetEmpty)
+ return true;
+
+ // Iterate pairwise through each of the value types making up the tail call
+ // and the corresponding return. For each one we want to know whether it's
+ // essentially going directly from the tail call to the ret, via operations
+ // that end up not generating any code.
+ //
+ // We allow a certain amount of covariance here. For example it's permitted
+ // for the tail call to define more bits than the ret actually cares about
+ // (e.g. via a truncate).
+ do {
+ if (CallEmpty) {
+ // We've exhausted the values produced by the tail call instruction, the
+ // rest are essentially undef. The type doesn't really matter, but we need
+ // *something*.
+ Type *SlotType = RetSubTypes.back()->getTypeAtIndex(RetPath.back());
+ CallVal = UndefValue::get(SlotType);
+ }
+
+ // The manipulations performed when we're looking through an insertvalue or
+ // an extractvalue would happen at the front of the RetPath list, so since
+ // we have to copy it anyway it's more efficient to create a reversed copy.
+ using std::copy;
+ SmallVector<unsigned, 4> TmpRetPath, TmpCallPath;
+ copy(RetPath.rbegin(), RetPath.rend(), std::back_inserter(TmpRetPath));
+ copy(CallPath.rbegin(), CallPath.rend(), std::back_inserter(TmpCallPath));
+
+ // Finally, we can check whether the value produced by the tail call at this
+ // index is compatible with the value we return.
+ if (!slotOnlyDiscardsData(RetVal, CallVal, TmpRetPath, TmpCallPath,
+ AllowDifferingSizes, TLI))
+ return false;
+
+ CallEmpty = !nextRealType(CallSubTypes, CallPath);
+ } while(nextRealType(RetSubTypes, RetPath));
+
+ return true;
}
OpenPOWER on IntegriCloud