/// 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) { // Try to look through V1; if V1 is not an instruction, it can't be looked // through. const Instruction *I = dyn_cast<Instruction>(V); if (!I || I->getNumOperands() == 0) return V; const Value *NoopInput = 0; 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 (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; V = NoopInput; } }
/// 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, const DataLayout &DL) { while (true) { // Try to look through V1; if V1 is not an instruction, it can't be looked // through. const Instruction *I = dyn_cast<Instruction>(V); if (!I || I->getNumOperands() == 0) return V; const Value *NoopInput = nullptr; 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()) && DL.getPointerSizeInBits() == 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()) && DL.getPointerSizeInBits() == 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 (auto CS = ImmutableCallSite(I)) { const Value *ReturnedOp = CS.getReturnedArgOperand(); if (ReturnedOp && isNoopBitcast(ReturnedOp->getType(), I->getType(), TLI)) NoopInput = ReturnedOp; } 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 (ValLoc.size() >= InsertLoc.size() && std::equal(InsertLoc.begin(), InsertLoc.end(), 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(); ValLoc.append(ExtractLoc.rbegin(), ExtractLoc.rend()); NoopInput = Op; } // Terminate if we couldn't find anything to look through. if (!NoopInput) return V; V = NoopInput; } }