llvm.org GIT mirror llvm / bbf596a
[Attributor] Use liveness during the creation of AAReturnedValues Summary: As one of the first attributes, and one of the complex ones, AAReturnedValues was not using liveness but we filtered the result after the fact. This change adds liveness usage during the creation. The algorithm is also improved and shorter. The new algorithm will collect returned values over time using the generic facilities that work with liveness already, e.g., genericValueTraversal which does not look at dead PHI node predecessors. A test to show how this leads to better results is included. Note: Unresolved calls and resolved calls are now tracked explicitly. Reviewers: uenoku, sstefan1 Subscribers: hiraditya, bollu, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D66120 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@368922 91177308-0d34-0410-b5e6-96231b3b80d8 Johannes Doerfert a month ago
3 changed file(s) with 278 addition(s) and 250 deletion(s). Raw diff Collapse all Expand all
271271 /// Return the Function surrounding the anchor value.
272272 ///
273273 ///{
274 Function &getAnchorScope() {
274 Function *getAnchorScope() {
275275 Value &V = getAnchorValue();
276276 if (isa(V))
277 return cast(V);
277 return &cast(V);
278278 if (isa(V))
279 return *cast(V).getParent();
279 return cast(V).getParent();
280280 if (isa(V))
281 return *cast(V).getFunction();
282 llvm_unreachable("No anchor scope");
283 }
284 const Function &getAnchorScope() const {
281 return cast(V).getFunction();
282 return nullptr;
283 }
284 const Function *getAnchorScope() const {
285285 return const_cast(this)->getAnchorScope();
286286 }
287287 ///}
10901090 : public IRAttribute {
10911091 AAReturnedValues(const IRPosition &IRP) : IRAttribute(IRP) {}
10921092
1093 /// Return an assumed unique return value if a single candidate is found. If
1094 /// there cannot be one, return a nullptr. If it is not clear yet, return the
1095 /// Optional::NoneType.
1096 Optional getAssumedUniqueReturnValue(Attributor &A) const;
1097
10931098 /// Check \p Pred on all returned values.
10941099 ///
10951100 /// This method will evaluate \p Pred on returned values and return
11021107 const function_ref &)>
11031108 &Pred) const = 0;
11041109
1110 using iterator = DenseMap>::iterator;
1111 using const_iterator =
1112 DenseMap>::const_iterator;
1113 virtual llvm::iterator_range returned_values() = 0;
1114 virtual llvm::iterator_range returned_values() const = 0;
1115
1116 virtual size_t getNumReturnValues() const = 0;
1117 virtual const SmallPtrSetImpl &getUnresolvedCalls() const = 0;
1118
11051119 /// Unique ID (due to the unique address)
11061120 static const char ID;
11071121 };
12531267 /// of instructions is live.
12541268 template bool isLiveInstSet(T begin, T end) const {
12551269 for (const auto &I : llvm::make_range(begin, end)) {
1256 assert(I->getFunction() == &getIRPosition().getAnchorScope() &&
1270 assert(I->getFunction() == getIRPosition().getAnchorScope() &&
12571271 "Instruction must be in the same anchor scope function.");
12581272
12591273 if (!isAssumedDead(I))
120120 }
121121 ///}
122122
123 template
124 using followValueCB_t = std::function;
125 template
126 using visitValueCB_t = std::function;
127
128 /// Recursively visit all values that might become \p InitV at some point. This
123 /// Recursively visit all values that might become \p IRP at some point. This
129124 /// will be done by looking through cast instructions, selects, phis, and calls
130 /// with the "returned" attribute. The callback \p FollowValueCB is asked before
131 /// a potential origin value is looked at. If no \p FollowValueCB is passed, a
132 /// default one is used that will make sure we visit every value only once. Once
133 /// we cannot look through the value any further, the callback \p VisitValueCB
134 /// is invoked and passed the current value and the \p State. To limit how much
135 /// effort is invested, we will never visit more than \p MaxValues values.
136 template
137 static bool genericValueTraversal(
138 Value *InitV, StateTy &State, visitValueCB_t &VisitValueCB,
139 followValueCB_t *FollowValueCB = nullptr, int MaxValues = 8) {
140
125 /// with the "returned" attribute. Once we cannot look through the value any
126 /// further, the callback \p VisitValueCB is invoked and passed the current
127 /// value, the \p State, and a flag to indicate if we stripped anything. To
128 /// limit how much effort is invested, we will never visit more values than
129 /// specified by \p MaxValues.
130 template
131 bool genericValueTraversal(
132 Attributor &A, IRPosition IRP, const AAType &QueryingAA, StateTy &State,
133 const function_ref &VisitValueCB,
134 int MaxValues = 8) {
135
136 const AAIsDead *LivenessAA = nullptr;
137 if (IRP.getAnchorScope())
138 LivenessAA = A.getAAFor(
139 QueryingAA, IRPosition::function(*IRP.getAnchorScope()));
140
141 // TODO: Use Positions here to allow context sensitivity in VisitValueCB
141142 SmallPtrSet Visited;
142 followValueCB_t DefaultFollowValueCB = [&](Value *Val, bool &) {
143 return Visited.insert(Val).second;
144 };
145
146 if (!FollowValueCB)
147 FollowValueCB = &DefaultFollowValueCB;
148
149143 SmallVector Worklist;
150 Worklist.push_back(InitV);
144 Worklist.push_back(&IRP.getAssociatedValue());
151145
152146 int Iteration = 0;
153147 do {
155149
156150 // Check if we should process the current value. To prevent endless
157151 // recursion keep a record of the values we followed!
158 if (!(*FollowValueCB)(V, State))
152 if (!Visited.insert(V).second)
159153 continue;
160154
161155 // Make sure we limit the compile time for complex expressions.
164158
165159 // Explicitly look through calls with a "returned" attribute if we do
166160 // not have a pointer as stripPointerCasts only works on them.
161 Value *NewV = nullptr;
167162 if (V->getType()->isPointerTy()) {
168 V = V->stripPointerCasts();
163 NewV = V->stripPointerCasts();
169164 } else {
170165 CallSite CS(V);
171166 if (CS && CS.getCalledFunction()) {
172 Value *NewV = nullptr;
173167 for (Argument &Arg : CS.getCalledFunction()->args())
174168 if (Arg.hasReturnedAttr()) {
175169 NewV = CS.getArgOperand(Arg.getArgNo());
176170 break;
177171 }
178 if (NewV) {
179 Worklist.push_back(NewV);
180 continue;
181 }
182172 }
173 }
174 if (NewV && NewV != V) {
175 Worklist.push_back(NewV);
176 continue;
183177 }
184178
185179 // Look through select instructions, visit both potential values.
189183 continue;
190184 }
191185
192 // Look through phi nodes, visit all operands.
186 // Look through phi nodes, visit all live operands.
193187 if (auto *PHI = dyn_cast(V)) {
194 Worklist.append(PHI->op_begin(), PHI->op_end());
188 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
189 const BasicBlock *IncomingBB = PHI->getIncomingBlock(u);
190 if (!LivenessAA ||
191 !LivenessAA->isAssumedDead(IncomingBB->getTerminator()))
192 Worklist.push_back(PHI->getIncomingValue(u));
193 }
195194 continue;
196195 }
197196
198197 // Once a leaf is reached we inform the user through the callback.
199 VisitValueCB(V, State);
198 VisitValueCB(*V, State, Iteration > 1);
200199 } while (!Worklist.empty());
201200
202201 // All values have been visited.
493492 ///
494493 /// If there is a unique returned value R, the manifest method will:
495494 /// - mark R with the "returned" attribute, if R is an argument.
496 ///
497 /// TODO: We should use liveness during construction of the returned values map
498 /// and before we set HasOverdefinedReturnedCalls.
499495 class AAReturnedValuesImpl : public AAReturnedValues, public AbstractState {
500496
501497 /// Mapping of values potentially returned by the associated function to the
502498 /// return instructions that might return them.
503499 DenseMap> ReturnedValues;
500
501 SmallPtrSet UnresolvedCalls;
504502
505503 /// State flags
506504 ///
507505 ///{
508506 bool IsFixed;
509507 bool IsValidState;
510 bool HasOverdefinedReturnedCalls;
511508 ///}
512
513 /// Collect values that could become \p V in the set \p Values, each mapped to
514 /// \p ReturnInsts.
515 void collectValuesRecursively(
516 Attributor &A, Value *V, SmallPtrSetImpl &ReturnInsts,
517 DenseMap> &Values) {
518
519 visitValueCB_t VisitValueCB = [&](Value *Val, bool &) {
520 assert(!isa(Val) ||
521 &getAnchorScope() == cast(Val)->getFunction());
522 Values[Val].insert(ReturnInsts.begin(), ReturnInsts.end());
523 };
524
525 bool UnusedBool;
526 bool Success = genericValueTraversal(V, UnusedBool, VisitValueCB);
527
528 // If we did abort the above traversal we haven't see all the values.
529 // Consequently, we cannot know if the information we would derive is
530 // accurate so we give up early.
531 if (!Success)
532 indicatePessimisticFixpoint();
533 }
534509
535510 public:
536511 AAReturnedValuesImpl(const IRPosition &IRP) : AAReturnedValues(IRP) {}
540515 // Reset the state.
541516 IsFixed = false;
542517 IsValidState = true;
543 HasOverdefinedReturnedCalls = false;
544518 ReturnedValues.clear();
545519
546 Function &F = getAnchorScope();
520 Function *F = getAssociatedFunction();
521 if (!F || !F->hasExactDefinition()) {
522 indicatePessimisticFixpoint();
523 return;
524 }
547525
548526 // The map from instruction opcodes to those instructions in the function.
549 auto &OpcodeInstMap = A.getInfoCache().getOpcodeInstMapForFunction(F);
527 auto &OpcodeInstMap = A.getInfoCache().getOpcodeInstMapForFunction(*F);
550528
551529 // Look through all arguments, if one is marked as returned we are done.
552 for (Argument &Arg : F.args()) {
530 for (Argument &Arg : F->args()) {
553531 if (Arg.hasReturnedAttr()) {
554
555532 auto &ReturnInstSet = ReturnedValues[&Arg];
556533 for (Instruction *RI : OpcodeInstMap[Instruction::Ret])
557534 ReturnInstSet.insert(cast(RI));
560537 return;
561538 }
562539 }
563
564 // If no argument was marked as returned we look at all return instructions
565 // and collect potentially returned values.
566 for (Instruction *RI : OpcodeInstMap[Instruction::Ret]) {
567 SmallPtrSet RISet({cast(RI)});
568 collectValuesRecursively(A, cast(RI)->getReturnValue(), RISet,
569 ReturnedValues);
570 }
571540 }
572541
573542 /// See AbstractAttribute::manifest(...).
582551 /// See AbstractAttribute::updateImpl(Attributor &A).
583552 ChangeStatus updateImpl(Attributor &A) override;
584553
554 llvm::iterator_range returned_values() override {
555 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
556 }
557
558 llvm::iterator_range returned_values() const override {
559 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
560 }
561
562 const SmallPtrSetImpl &getUnresolvedCalls() const override {
563 return UnresolvedCalls;
564 }
565
585566 /// Return the number of potential return values, -1 if unknown.
586 size_t getNumReturnValues() const {
567 size_t getNumReturnValues() const override {
587568 return isValidState() ? ReturnedValues.size() : -1;
588569 }
589570
620601 }
621602 };
622603
623 struct AAReturnedValuesFunction final : public AAReturnedValuesImpl {
624 AAReturnedValuesFunction(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
625
626 /// See AbstractAttribute::trackStatistics()
627 void trackStatistics() const override {
628 STATS_DECL_AND_TRACK_ARG_ATTR(returned)
629 }
630 };
631
632604 ChangeStatus AAReturnedValuesImpl::manifest(Attributor &A) {
633605 ChangeStatus Changed = ChangeStatus::UNCHANGED;
634606
659631 const std::string AAReturnedValuesImpl::getAsStr() const {
660632 return (isAtFixpoint() ? "returns(#" : "may-return(#") +
661633 (isValidState() ? std::to_string(getNumReturnValues()) : "?") +
662 ")[OD: " + std::to_string(HasOverdefinedReturnedCalls) + "]";
634 ")[#UC: " + std::to_string(UnresolvedCalls.size()) + "]";
663635 }
664636
665637 Optional
706678 Value *RV = It.first;
707679 const SmallPtrSetImpl &RetInsts = It.second;
708680
709 ImmutableCallSite ICS(RV);
710 if (ICS && !HasOverdefinedReturnedCalls)
681 CallBase *CB = dyn_cast(RV);
682 if (CB && !UnresolvedCalls.count(CB))
711683 continue;
712684
713685 if (!Pred(*RV, RetInsts))
718690 }
719691
720692 ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
721
722 // Check if we know of any values returned by the associated function,
723 // if not, we are done.
724 if (getNumReturnValues() == 0) {
725 indicateOptimisticFixpoint();
726 return ChangeStatus::UNCHANGED;
727 }
728
729 // Check if any of the returned values is a call site we can refine.
730 decltype(ReturnedValues) AddRVs;
731 bool HasCallSite = false;
732
733 // Keep track of any change to trigger updates on dependent attributes.
734 ChangeStatus Changed = ChangeStatus::UNCHANGED;
735
736 auto *LivenessAA = A.getAAFor(*this, getIRPosition());
737
738 // Look at all returned call sites.
693 size_t NumUnresolvedCalls = UnresolvedCalls.size();
694 bool Changed = false;
695
696 // State used in the value traversals starting in returned values.
697 struct RVState {
698 // The map in which we collect return values -> return instrs.
699 decltype(ReturnedValues) &RetValsMap;
700 // The flag to indicate a change.
701 bool Changed;
702 // The return instrs we come from.
703 SmallPtrSet RetInsts;
704 };
705
706 // Callback for a leaf value returned by the associated function.
707 auto VisitValueCB = [](Value &Val, RVState &RVS, bool) {
708 auto Size = RVS.RetValsMap[&Val].size();
709 RVS.RetValsMap[&Val].insert(RVS.RetInsts.begin(), RVS.RetInsts.end());
710 bool Inserted = RVS.RetValsMap[&Val].size() != Size;
711 RVS.Changed |= Inserted;
712 LLVM_DEBUG({
713 if (Inserted)
714 dbgs() << "[AAReturnedValues] 1 Add new returned value " << Val
715 << " => " << RVS.RetInsts.size() << "\n";
716 });
717 };
718
719 // Helper method to invoke the generic value traversal.
720 auto VisitReturnedValue = [&](Value &RV, RVState &RVS) {
721 IRPosition RetValPos = IRPosition::value(RV);
722 return genericValueTraversal(A, RetValPos, *this,
723 RVS, VisitValueCB);
724 };
725
726 // Callback for all "return intructions" live in the associated function.
727 auto CheckReturnInst = [this, &VisitReturnedValue, &Changed](Instruction &I) {
728 ReturnInst &Ret = cast(I);
729 RVState RVS({ReturnedValues, false});
730 RVS.RetInsts.insert(&Ret);
731 Changed |= RVS.Changed;
732 return VisitReturnedValue(*Ret.getReturnValue(), RVS);
733 };
734
735 // Start by discovering returned values from all live returned instructions in
736 // the associated function.
737 if (!A.checkForAllInstructions(CheckReturnInst, *this, {Instruction::Ret}))
738 return indicatePessimisticFixpoint();
739
740 // Once returned values "directly" present in the code are handled we try to
741 // resolve returned calls.
742 decltype(ReturnedValues) NewRVsMap;
739743 for (auto &It : ReturnedValues) {
740 SmallPtrSet &ReturnInsts = It.second;
741 Value *RV = It.first;
742
743 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Potentially returned value " << *RV
744 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Returned value: " << *It.first
745 << " by #" << It.second.size() << " RIs\n");
746 CallBase *CB = dyn_cast(It.first);
747 if (!CB || UnresolvedCalls.count(CB))
748 continue;
749
750 const auto *RetValAAPtr =
751 A.getAAFor(*this, IRPosition::callsite_function(*CB));
752
753 // Skip dead ends, thus if we do not know anything about the returned
754 // call we mark it as unresolved and it will stay that way.
755 if (!RetValAAPtr || !RetValAAPtr->getState().isValidState()) {
756 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
757 << "\n");
758 UnresolvedCalls.insert(CB);
759 continue;
760 }
761
762 const auto &RetValAA = *RetValAAPtr;
763 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Found another AAReturnedValues: "
764 << static_cast(RetValAA)
744765 << "\n");
745766
746 // Only call sites can change during an update, ignore the rest.
747 CallSite RetCS(RV);
748 if (!RetCS)
749 continue;
750
751 // For now, any call site we see will prevent us from directly fixing the
752 // state. However, if the information on the callees is fixed, the call
753 // sites will be removed and we will fix the information for this state.
754 HasCallSite = true;
755
756 // Ignore dead ReturnValues.
757 if (LivenessAA &&
758 !LivenessAA->isLiveInstSet(ReturnInsts.begin(), ReturnInsts.end())) {
759 LLVM_DEBUG(dbgs() << "[AAReturnedValues] all returns are assumed dead, "
760 "skip it for now\n");
761 continue;
762 }
763
764 // Try to find a assumed unique return value for the called function.
765 auto *RetCSAA = A.getAAFor(
766 *this, IRPosition::callsite_returned(RetCS));
767 if (!RetCSAA) {
768 if (!HasOverdefinedReturnedCalls)
769 Changed = ChangeStatus::CHANGED;
770 HasOverdefinedReturnedCalls = true;
771 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Returned call site (" << *RV
772 << ") with " << (RetCSAA ? "invalid" : "no")
773 << " associated state\n");
774 continue;
775 }
776
777 // Try to find a assumed unique return value for the called function.
778 Optional AssumedUniqueRV = RetCSAA->getAssumedUniqueReturnValue(A);
779
780 // If no assumed unique return value was found due to the lack of
781 // candidates, we may need to resolve more calls (through more update
782 // iterations) or the called function will not return. Either way, we
783 // simply stick with the call sites as return values. Because there were
784 // not multiple possibilities, we do not treat it as overdefined.
785 if (!AssumedUniqueRV.hasValue())
786 continue;
787
788 // If multiple, non-refinable values were found, there cannot be a unique
789 // return value for the called function. The returned call is overdefined!
790 if (!AssumedUniqueRV.getValue()) {
791 if (!HasOverdefinedReturnedCalls)
792 Changed = ChangeStatus::CHANGED;
793 HasOverdefinedReturnedCalls = true;
794 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Returned call site has multiple "
795 "potentially returned values\n");
796 continue;
797 }
798
799 LLVM_DEBUG({
800 bool UniqueRVIsKnown = RetCSAA->isAtFixpoint();
801 dbgs() << "[AAReturnedValues] Returned call site "
802 << (UniqueRVIsKnown ? "known" : "assumed")
803 << " unique return value: " << *AssumedUniqueRV << "\n";
804 });
805
806 // The assumed unique return value.
807 Value *AssumedRetVal = AssumedUniqueRV.getValue();
808
809 // If the assumed unique return value is an argument, lookup the matching
810 // call site operand and recursively collect new returned values.
811 // If it is not an argument, it is just put into the set of returned
812 // values as we would have already looked through casts, phis, and similar
813 // values.
814 if (Argument *AssumedRetArg = dyn_cast(AssumedRetVal))
815 collectValuesRecursively(A,
816 RetCS.getArgOperand(AssumedRetArg->getArgNo()),
817 ReturnInsts, AddRVs);
818 else
819 AddRVs[AssumedRetVal].insert(ReturnInsts.begin(), ReturnInsts.end());
820 }
821
822 for (auto &It : AddRVs) {
767 // If we know something but not everyting about the returned values, keep
768 // track of that too. Hence, remember transitively unresolved calls.
769 UnresolvedCalls.insert(RetValAA.getUnresolvedCalls().begin(),
770 RetValAA.getUnresolvedCalls().end());
771
772 // Now track transitively returned values.
773 for (auto &RetValAAIt : RetValAA.returned_values()) {
774 Value *RetVal = RetValAAIt.first;
775 if (Argument *Arg = dyn_cast(RetVal)) {
776 // Arguments are mapped to call site operands and we begin the traversal
777 // again.
778 RVState RVS({NewRVsMap, false, RetValAAIt.second});
779 VisitReturnedValue(*CB->getArgOperand(Arg->getArgNo()), RVS);
780 continue;
781 } else if (isa(RetVal)) {
782 // Call sites are resolved by the callee attribute over time, no need to
783 // do anything for us.
784 continue;
785 } else if (isa(RetVal)) {
786 // Constants are valid everywhere, we can simply take them.
787 NewRVsMap[RetVal].insert(It.second.begin(), It.second.end());
788 continue;
789 }
790 // Anything that did not fit in the above categories cannot be resolved,
791 // mark the call as unresolved.
792 LLVM_DEBUG(dbgs() << "[AAReturnedValues] transitively returned value "
793 "cannot be translated: "
794 << *RetVal << "\n");
795 UnresolvedCalls.insert(CB);
796 }
797 }
798
799 // To avoid modifications to the ReturnedValues map while we iterate over it
800 // we kept record of potential new entries in a copy map, NewRVsMap.
801 for (auto &It : NewRVsMap) {
823802 assert(!It.second.empty() && "Entry does not add anything.");
824803 auto &ReturnInsts = ReturnedValues[It.first];
825804 for (ReturnInst *RI : It.second)
826805 if (ReturnInsts.insert(RI).second) {
827806 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Add new returned value "
828807 << *It.first << " => " << *RI << "\n");
829 Changed = ChangeStatus::CHANGED;
808 Changed = true;
830809 }
831810 }
832811
833 // If there is no call site in the returned values we are done.
834 if (!HasCallSite) {
835 indicateOptimisticFixpoint();
836 return ChangeStatus::CHANGED;
837 }
838
839 return Changed;
840 }
812 Changed |= (NumUnresolvedCalls != UnresolvedCalls.size());
813 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
814 }
815
816 struct AAReturnedValuesFunction final : public AAReturnedValuesImpl {
817 AAReturnedValuesFunction(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
818
819 /// See AbstractAttribute::trackStatistics()
820 void trackStatistics() const override {
821 STATS_DECL_AND_TRACK_ARG_ATTR(returned)
822 }
823 };
841824
842825 /// ------------------------ NoSync Function Attribute -------------------------
843826
12381221 bool containsPossiblyEndlessLoop(Function &F) { return containsCycle(F); }
12391222
12401223 void AAWillReturnFunction::initialize(Attributor &A) {
1241 Function &F = getAnchorScope();
1224 Function &F = *getAnchorScope();
12421225
12431226 if (containsPossiblyEndlessLoop(F))
12441227 indicatePessimisticFixpoint();
12871270
12881271 /// See AbstractAttriubute::initialize(...).
12891272 void initialize(Attributor &A) override {
1290 Function &F = getAnchorScope();
1273 Function &F = *getAnchorScope();
12911274
12921275 // Already noalias.
12931276 if (F.returnDoesNotAlias()) {
13471330 AAIsDeadImpl(const IRPosition &IRP) : AAIsDead(IRP) {}
13481331
13491332 void initialize(Attributor &A) override {
1350 const Function &F = getAnchorScope();
1333 const Function &F = *getAnchorScope();
13511334
13521335 ToBeExploredPaths.insert(&(F.getEntryBlock().front()));
13531336 AssumedLiveBlocks.insert(&(F.getEntryBlock()));
13701353 /// See AbstractAttribute::getAsStr().
13711354 const std::string getAsStr() const override {
13721355 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
1373 std::to_string(getAnchorScope().size()) + "][#NRI " +
1356 std::to_string(getAnchorScope()->size()) + "][#NRI " +
13741357 std::to_string(NoReturnCalls.size()) + "]";
13751358 }
13761359
13801363 "Attempted to manifest an invalid state!");
13811364
13821365 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
1383 const Function &F = getAnchorScope();
1366 const Function &F = *getAssociatedFunction();
13841367
13851368 // Flag to determine if we can change an invoke to a call assuming the
13861369 // callee is nounwind. This is not possible if the personality of the
14421425
14431426 /// See AAIsDead::isAssumedDead(BasicBlock *).
14441427 bool isAssumedDead(const BasicBlock *BB) const override {
1445 assert(BB->getParent() == &getAnchorScope() &&
1428 assert(BB->getParent() == getAnchorScope() &&
14461429 "BB must be in the same anchor scope function.");
14471430
14481431 if (!getAssumed())
14571440
14581441 /// See AAIsDead::isAssumed(Instruction *I).
14591442 bool isAssumedDead(const Instruction *I) const override {
1460 assert(I->getParent()->getParent() == &getAnchorScope() &&
1443 assert(I->getParent()->getParent() == getAnchorScope() &&
14611444 "Instruction must be in the same anchor scope function.");
14621445
14631446 if (!getAssumed())
15031486 STATS_DECL(DeadBlocks, Function,
15041487 "Number of basic blocks classified as dead");
15051488 BUILD_STAT_NAME(DeadBlocks, Function) +=
1506 getAnchorScope().size() - AssumedLiveBlocks.size();
1489 getAnchorScope()->size() - AssumedLiveBlocks.size();
15071490 STATS_DECL(PartiallyDeadBlocks, Function,
15081491 "Number of basic blocks classified as partially dead");
15091492 BUILD_STAT_NAME(PartiallyDeadBlocks, Function) += NoReturnCalls.size();
16011584 }
16021585 }
16031586
1604 LLVM_DEBUG(
1605 dbgs() << "[AAIsDead] AssumedLiveBlocks: " << AssumedLiveBlocks.size()
1606 << " Total number of blocks: " << getAnchorScope().size() << "\n");
1587 LLVM_DEBUG(dbgs() << "[AAIsDead] AssumedLiveBlocks: "
1588 << AssumedLiveBlocks.size() << " Total number of blocks: "
1589 << getAnchorScope()->size() << "\n");
16071590
16081591 // If we know everything is live there is no need to query for liveness.
16091592 if (NoReturnCalls.empty() &&
1610 getAnchorScope().size() == AssumedLiveBlocks.size()) {
1593 getAnchorScope()->size() == AssumedLiveBlocks.size()) {
16111594 // Indicating a pessimistic fixpoint will cause the state to be "invalid"
16121595 // which will cause the Attributor to not return the AAIsDead on request,
16131596 // which will prevent us from querying isAssumedDead().
18231806 return calcDifferenceIfBaseIsNonNull(
18241807 DL.getTypeStoreSize(Base->getType()->getPointerElementType()),
18251808 Offset.getSExtValue(),
1826 !NullPointerIsDefined(&getAnchorScope(),
1809 !NullPointerIsDefined(getAnchorScope(),
18271810 V.getType()->getPointerAddressSpace()));
18281811
18291812 IsNonNull = false;
22292212 if (!AARetVal || !AARetVal->getState().isValidState())
22302213 return false;
22312214
2232 auto *LivenessAA =
2233 getAAFor(QueryingAA, IRPosition::function(*AssociatedFunction));
2234 if (!LivenessAA)
2235 return AARetVal->checkForAllReturnedValuesAndReturnInsts(Pred);
2236
2237 auto LivenessFilter = [&](Value &RV,
2238 const SmallPtrSetImpl &ReturnInsts) {
2239 SmallPtrSet FilteredReturnInsts;
2240 for (ReturnInst *RI : ReturnInsts)
2241 if (!LivenessAA->isAssumedDead(RI))
2242 FilteredReturnInsts.insert(RI);
2243 if (!FilteredReturnInsts.empty())
2244 return Pred(RV, FilteredReturnInsts);
2245 return true;
2246 };
2247
2248 return AARetVal->checkForAllReturnedValuesAndReturnInsts(LivenessFilter);
2215 return AARetVal->checkForAllReturnedValuesAndReturnInsts(Pred);
22492216 }
22502217
22512218 bool Attributor::checkForAllReturnedValues(
22622229 if (!AARetVal || !AARetVal->getState().isValidState())
22632230 return false;
22642231
2265 auto *LivenessAA =
2266 getAAFor(QueryingAA, IRPosition::function(*AssociatedFunction));
2267 if (!LivenessAA)
2268 return AARetVal->checkForAllReturnedValuesAndReturnInsts(
2269 [&](Value &RV, const SmallPtrSetImpl &) {
2270 return Pred(RV);
2271 });
2272
2273 auto LivenessFilter = [&](Value &RV,
2274 const SmallPtrSetImpl &ReturnInsts) {
2275 if (LivenessAA->isLiveInstSet(ReturnInsts.begin(), ReturnInsts.end()))
2276 return Pred(RV);
2277 return true;
2278 };
2279
2280 return AARetVal->checkForAllReturnedValuesAndReturnInsts(LivenessFilter);
2232 return AARetVal->checkForAllReturnedValuesAndReturnInsts(
2233 [&](Value &RV, const SmallPtrSetImpl &) {
2234 return Pred(RV);
2235 });
22812236 }
22822237
22832238 bool Attributor::checkForAllInstructions(
292292 ;
293293 ; FNATTR: define i32* @rt2_helper(i32* %a)
294294 ; FNATTR: define i32* @rt2(i32* readnone %a, i32* readnone %b)
295 ; BOTH: define i32* @rt2_helper(i32* %a)
295 ; BOTH: define i32* @rt2_helper(i32* returned %a)
296296 ; BOTH: define i32* @rt2(i32* readnone %a, i32* readnone %b)
297297 define i32* @rt2_helper(i32* %a) #0 {
298298 entry:
713713 ;
714714 ; FNATTR: define i32 @deadblockcall1(i32 %A)
715715 ; FNATTR: define i32 @deadblockcall2(i32 %A)
716 ; FNATTR: define i32 @deadblockphi1(i32 %A)
717 ; FNATTR: define i32 @deadblockphi2(i32 %A)
716718 ; ATTRIBUTOR: define i32 @deadblockcall1(i32 returned %A)
717719 ; ATTRIBUTOR: define i32 @deadblockcall2(i32 returned %A)
720 ; ATTRIBUTOR: define i32 @deadblockphi1(i32 returned %A)
721 ; ATTRIBUTOR: define i32 @deadblockphi2(i32 returned %A)
718722 ; BOTH: define i32 @deadblockcall1(i32 returned %A)
719723 ; BOTH: define i32 @deadblockcall2(i32 returned %A)
724 ; BOTH: define i32 @deadblockphi1(i32 returned %A)
725 ; BOTH: define i32 @deadblockphi2(i32 returned %A)
720726 define i32 @deadblockcall1(i32 %A) #0 {
721727 entry:
722728 ret i32 %A
738744 ret i32 %C
739745 }
740746
747 define i32 @deadblockphi1(i32 %A) #0 {
748 entry:
749 br label %r
750 unreachableblock1:
751 %B = call i32 @deadblockcall_helper(i32 %B)
752 ret i32 %B
753 unreachableblock2:
754 %C = call i32 @deadblockcall1(i32 %C)
755 br label %r
756 r:
757 %PHI = phi i32 [%A, %entry], [%C, %unreachableblock2]
758 ret i32 %PHI
759 }
760
761 define i32 @deadblockphi2(i32 %A) #0 {
762 entry:
763 br label %r
764 unreachableblock1:
765 %B = call i32 @deadblockcall_helper(i32 %B)
766 br label %unreachableblock3
767 unreachableblock2:
768 %C = call i32 @deadblockcall1(i32 %C)
769 br label %unreachableblock3
770 unreachableblock3:
771 %PHI1 = phi i32 [%B, %unreachableblock1], [%C, %unreachableblock2]
772 br label %r
773 r:
774 %PHI2 = phi i32 [%A, %entry], [%PHI1, %unreachableblock3]
775 ret i32 %PHI2
776 }
777
778 declare void @noreturn() noreturn;
779
780 define i32 @deadblockphi3(i32 %A, i1 %c) #0 {
781 entry:
782 br i1 %c, label %r, label %unreachablecall
783 unreachablecall:
784 call void @noreturn();
785 %B = call i32 @deadblockcall_helper(i32 0)
786 br label %unreachableblock3
787 unreachableblock2:
788 %C = call i32 @deadblockcall1(i32 %C)
789 br label %unreachableblock3
790 unreachableblock3:
791 %PHI1 = phi i32 [%B, %unreachablecall], [%C, %unreachableblock2]
792 br label %r
793 r:
794 %PHI2 = phi i32 [%A, %entry], [%PHI1, %unreachableblock3]
795 ret i32 %PHI2
796 }
797
798
741799 attributes #0 = { noinline nounwind uwtable }
742800
743801 ; BOTH-NOT: attributes #
747805 ; BOTH-DAG: attributes #{{[0-9]*}} = { noinline nounwind uwtable }
748806 ; BOTH-DAG: attributes #{{[0-9]*}} = { nofree noinline nosync nounwind readnone uwtable willreturn }
749807 ; BOTH-DAG: attributes #{{[0-9]*}} = { nofree noinline nosync nounwind uwtable willreturn }
808 ; BOTH-DAG: attributes #{{[0-9]*}} = { noreturn }
750809 ; BOTH-NOT: attributes #