Index: include/llvm/IR/ModuleSummaryIndex.h =================================================================== --- include/llvm/IR/ModuleSummaryIndex.h +++ include/llvm/IR/ModuleSummaryIndex.h @@ -359,6 +359,45 @@ /// Get function attribute flags. FFlags &fflags() { return FunFlags; } + /// Iterator for a callees in a function summary. + class const_iterator + : public std::iterator { + std::vector::const_iterator I; + const FunctionSummary *fsumFromEdge(const EdgeTy &P) { + if (P.first.Ref && P.first.getSummaryList().size()) + return cast(P.first.getSummaryList().front().get()); + + // Create an empty functionsummary in the case of an external function + // (since scc_iterator doesn't accept nullptrs) + auto F = llvm::make_unique( + GVFlags(GlobalValue::LinkageTypes::AvailableExternallyLinkage, true, + false), + 0, FFlags{}, std::vector(), std::vector(), + std::vector(), std::vector(), + std::vector(), std::vector(), + std::vector()); + F->setOriginalName(P.first.Ref ? P.first.getGUID() : 0); + return F.get(); + } + + public: + const_iterator(std::vector::const_iterator I) : I(I){}; + const_iterator operator++(int) { + I++; + return *this; + } + bool operator==(const const_iterator &rhs) const { return I == rhs.I; } + bool operator!=(const const_iterator &rhs) const { return I != rhs.I; } + const FunctionSummary *operator*() { return fsumFromEdge(*I); } + }; + + const_iterator call_summaries_begin() const { + return const_iterator(CallGraphEdgeList.begin()); + } + const_iterator call_summaries_end() const { + return const_iterator(CallGraphEdgeList.end()); + } + /// Get the instruction count recorded for this function. unsigned instCount() const { return InstCount; } @@ -772,6 +811,39 @@ StringMap &ModuleToDefinedGVSummaries) const; }; +/// GraphTraits definition to build SCC for the index +template <> struct GraphTraits { + typedef const FunctionSummary *NodeRef; + typedef FunctionSummary::const_iterator ChildIteratorType; + + // Use the first callee as the entry node + static NodeRef getEntryNode(const FunctionSummary *F) { + if (F->call_summaries_begin() != F->call_summaries_end()) + return *(F->call_summaries_begin()); + + // use a dummy functionsummary when there is no entry node + auto S = llvm::make_unique( + FunctionSummary::GVFlags( + GlobalValue::LinkageTypes::AvailableExternallyLinkage, true, false), + 0, FunctionSummary::FFlags{}, std::vector(), + std::vector(), + std::vector(), + std::vector(), + std::vector(), + std::vector(), + std::vector()); + return S.get(); + } + + static ChildIteratorType child_begin(NodeRef N) { + return N->call_summaries_begin(); + } + + static ChildIteratorType child_end(NodeRef N) { + return N->call_summaries_end(); + } +}; + } // end namespace llvm #endif // LLVM_IR_MODULESUMMARYINDEX_H