Skip to content

Commit e1a586a

Browse files
author
git apple-llvm automerger
committed
Merge commit 'f648eb9f614c' from apple/main into swift/next
2 parents b99229d + f648eb9 commit e1a586a

File tree

7 files changed

+54
-146
lines changed

7 files changed

+54
-146
lines changed

llvm/include/llvm/Analysis/LazyCallGraph.h

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,6 +1009,10 @@ class LazyCallGraph {
10091009
/// remain active and reachable.
10101010
bool isLibFunction(Function &F) const { return LibFunctions.count(&F); }
10111011

1012+
/// Helper to initialize a new node created outside of creating SCCs and add
1013+
/// it to the NodeMap. e.g. when a function is outlined.
1014+
Node &initNode(Node &N, LazyCallGraph::SCC &C);
1015+
10121016
///@{
10131017
/// \name Pre-SCC Mutation API
10141018
///
@@ -1058,13 +1062,6 @@ class LazyCallGraph {
10581062
/// fully visited by the DFS prior to calling this routine.
10591063
void removeDeadFunction(Function &F);
10601064

1061-
/// Introduce a node for the function \p NewF in the SCC \p C.
1062-
void addNewFunctionIntoSCC(Function &NewF, SCC &C);
1063-
1064-
/// Introduce a node for the function \p NewF, as a single node in a
1065-
/// new SCC, in the RefSCC \p RC.
1066-
void addNewFunctionIntoRefSCC(Function &NewF, RefSCC &RC);
1067-
10681065
///@}
10691066

10701067
///@{
@@ -1171,13 +1168,6 @@ class LazyCallGraph {
11711168
/// Helper to update pointers back to the graph object during moves.
11721169
void updateGraphPtrs();
11731170

1174-
/// Helper to insert a new function, add it to the NodeMap, and populate its
1175-
/// node.
1176-
Node &createNode(Function &F);
1177-
1178-
/// Helper to add the given Node \p N to the SCCMap, mapped to the SCC \p C.
1179-
void addNodeToSCC(SCC &C, Node &N);
1180-
11811171
/// Allocates an SCC and constructs it using the graph allocator.
11821172
///
11831173
/// The arguments are forwarded to the constructor.

llvm/lib/Analysis/CGSCCPassManager.cpp

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@ static LazyCallGraph::SCC &updateCGAndAnalysisManagerForPass(
459459
SmallSetVector<Node *, 4> DemotedCallTargets;
460460
SmallSetVector<Node *, 4> NewCallEdges;
461461
SmallSetVector<Node *, 4> NewRefEdges;
462+
SmallSetVector<Node *, 4> NewNodes;
462463

463464
// First walk the function and handle all called functions. We do this first
464465
// because if there is a single call edge, whether there are ref edges is
@@ -467,19 +468,23 @@ static LazyCallGraph::SCC &updateCGAndAnalysisManagerForPass(
467468
if (auto *CB = dyn_cast<CallBase>(&I))
468469
if (Function *Callee = CB->getCalledFunction())
469470
if (Visited.insert(Callee).second && !Callee->isDeclaration()) {
470-
Node &CalleeN = *G.lookup(*Callee);
471-
Edge *E = N->lookup(CalleeN);
471+
Node *CalleeN = G.lookup(*Callee);
472+
if (!CalleeN) {
473+
CalleeN = &G.get(*Callee);
474+
NewNodes.insert(CalleeN);
475+
}
476+
Edge *E = N->lookup(*CalleeN);
472477
assert((E || !FunctionPass) &&
473478
"No function transformations should introduce *new* "
474479
"call edges! Any new calls should be modeled as "
475480
"promoted existing ref edges!");
476-
bool Inserted = RetainedEdges.insert(&CalleeN).second;
481+
bool Inserted = RetainedEdges.insert(CalleeN).second;
477482
(void)Inserted;
478483
assert(Inserted && "We should never visit a function twice.");
479484
if (!E)
480-
NewCallEdges.insert(&CalleeN);
485+
NewCallEdges.insert(CalleeN);
481486
else if (!E->isCall())
482-
PromotedRefTargets.insert(&CalleeN);
487+
PromotedRefTargets.insert(CalleeN);
483488
}
484489

485490
// Now walk all references.
@@ -490,22 +495,29 @@ static LazyCallGraph::SCC &updateCGAndAnalysisManagerForPass(
490495
Worklist.push_back(C);
491496

492497
auto VisitRef = [&](Function &Referee) {
493-
Node &RefereeN = *G.lookup(Referee);
494-
Edge *E = N->lookup(RefereeN);
498+
Node *RefereeN = G.lookup(Referee);
499+
if (!RefereeN) {
500+
RefereeN = &G.get(Referee);
501+
NewNodes.insert(RefereeN);
502+
}
503+
Edge *E = N->lookup(*RefereeN);
495504
assert((E || !FunctionPass) &&
496505
"No function transformations should introduce *new* ref "
497506
"edges! Any new ref edges would require IPO which "
498507
"function passes aren't allowed to do!");
499-
bool Inserted = RetainedEdges.insert(&RefereeN).second;
508+
bool Inserted = RetainedEdges.insert(RefereeN).second;
500509
(void)Inserted;
501510
assert(Inserted && "We should never visit a function twice.");
502511
if (!E)
503-
NewRefEdges.insert(&RefereeN);
512+
NewRefEdges.insert(RefereeN);
504513
else if (E->isCall())
505-
DemotedCallTargets.insert(&RefereeN);
514+
DemotedCallTargets.insert(RefereeN);
506515
};
507516
LazyCallGraph::visitReferences(Worklist, Visited, VisitRef);
508517

518+
for (Node *NewNode : NewNodes)
519+
G.initNode(*NewNode, *C);
520+
509521
// Handle new ref edges.
510522
for (Node *RefTarget : NewRefEdges) {
511523
SCC &TargetC = *G.lookupSCC(*RefTarget);

llvm/lib/Analysis/LazyCallGraph.cpp

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1565,21 +1565,6 @@ void LazyCallGraph::removeDeadFunction(Function &F) {
15651565
// allocators.
15661566
}
15671567

1568-
void LazyCallGraph::addNewFunctionIntoSCC(Function &NewF, SCC &C) {
1569-
addNodeToSCC(C, createNode(NewF));
1570-
}
1571-
1572-
void LazyCallGraph::addNewFunctionIntoRefSCC(Function &NewF, RefSCC &RC) {
1573-
Node &N = createNode(NewF);
1574-
1575-
auto *C = createSCC(RC, SmallVector<Node *, 1>());
1576-
addNodeToSCC(*C, N);
1577-
1578-
auto Index = RC.SCCIndices.size();
1579-
RC.SCCIndices[C] = Index;
1580-
RC.SCCs.push_back(C);
1581-
}
1582-
15831568
LazyCallGraph::Node &LazyCallGraph::insertInto(Function &F, Node *&MappedN) {
15841569
return *new (MappedN = BPA.Allocate()) Node(*this, F);
15851570
}
@@ -1594,17 +1579,13 @@ void LazyCallGraph::updateGraphPtrs() {
15941579
RC->G = this;
15951580
}
15961581

1597-
LazyCallGraph::Node &LazyCallGraph::createNode(Function &F) {
1598-
Node &N = get(F);
1599-
NodeMap[&F] = &N;
1582+
LazyCallGraph::Node &LazyCallGraph::initNode(Node &N, LazyCallGraph::SCC &C) {
1583+
NodeMap[&N.getFunction()] = &N;
16001584
N.DFSNumber = N.LowLink = -1;
16011585
N.populate();
1602-
return N;
1603-
}
1604-
1605-
void LazyCallGraph::addNodeToSCC(LazyCallGraph::SCC &C, Node &N) {
16061586
C.Nodes.push_back(&N);
16071587
SCCMap[&N] = &C;
1588+
return N;
16081589
}
16091590

16101591
template <typename RootsT, typename GetBeginT, typename GetEndT,

llvm/lib/Transforms/Coroutines/CoroSplit.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,13 +1484,6 @@ static void updateCallGraphAfterCoroutineSplit(
14841484

14851485
postSplitCleanup(N.getFunction());
14861486

1487-
// To insert the newly created coroutine funclets 'f.resume', 'f.destroy', and
1488-
// 'f.cleanup' into the same SCC as the coroutine 'f' they were outlined from,
1489-
// we make use of the CallGraphUpdater class, which can modify the internal
1490-
// state of the LazyCallGraph.
1491-
for (Function *Clone : Clones)
1492-
CG.addNewFunctionIntoRefSCC(*Clone, C.getOuterRefSCC());
1493-
14941487
// We've inserted instructions into coroutine 'f' that reference the three new
14951488
// coroutine funclets. We must now update the call graph so that reference
14961489
// edges between 'f' and its funclets are added to it. LazyCallGraph only

llvm/lib/Transforms/Utils/CallGraphUpdater.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,6 @@ void CallGraphUpdater::reanalyzeFunction(Function &Fn) {
9999
void CallGraphUpdater::registerOutlinedFunction(Function &NewFn) {
100100
if (CG)
101101
CG->addToCallGraph(&NewFn);
102-
else if (LCG)
103-
LCG->addNewFunctionIntoSCC(NewFn, *SCC);
104102
}
105103

106104
void CallGraphUpdater::removeFunction(Function &DeadFn) {

llvm/unittests/Analysis/CGSCCPassManagerTest.cpp

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1743,7 +1743,6 @@ TEST_F(CGSCCPassManagerTest, TestInsertionOfNewRefSCC) {
17431743
// single node in a new SCC, into the call graph. As a result
17441744
// the call graph is composed of a single RefSCC with two SCCs:
17451745
// [(f), (g)].
1746-
CG.addNewFunctionIntoRefSCC(*G, C.getOuterRefSCC());
17471746

17481747
// "Demote" the 'f -> f' call egde to a ref edge.
17491748
// 1. Erase the call edge from 'f' to 'f'.
@@ -1785,6 +1784,25 @@ TEST_F(CGSCCPassManagerTest, TestInsertionOfNewRefSCCMutuallyRecursive) {
17851784
if (F.getName() != "f")
17861785
continue;
17871786

1787+
// Create mutually recursive functions (call) 'g1' and 'g2'.
1788+
auto *G1 = Function::Create(F.getFunctionType(), F.getLinkage(),
1789+
F.getAddressSpace(), "g1", F.getParent());
1790+
auto *G2 = Function::Create(F.getFunctionType(), F.getLinkage(),
1791+
F.getAddressSpace(), "g2", F.getParent());
1792+
BasicBlock *G1BB =
1793+
BasicBlock::Create(F.getParent()->getContext(), "entry", G1);
1794+
BasicBlock *G2BB =
1795+
BasicBlock::Create(F.getParent()->getContext(), "entry", G2);
1796+
(void)CallInst::Create(G1, {}, "", G1BB);
1797+
(void)ReturnInst::Create(G1->getContext(), G1BB);
1798+
(void)CallInst::Create(G2, {}, "", G1BB);
1799+
(void)ReturnInst::Create(G2->getContext(), G2BB);
1800+
1801+
// Add 'f -> g1' call edge.
1802+
(void)CallInst::Create(G1, {}, "", &F.getEntryBlock().front());
1803+
// Add 'f -> g2' call edge.
1804+
(void)CallInst::Create(G2, {}, "", &F.getEntryBlock().front());
1805+
17881806
// Create mutually recursive functions (ref only) 'h1' and 'h2'.
17891807
auto *H1 = Function::Create(F.getFunctionType(), F.getLinkage(),
17901808
F.getAddressSpace(), "h1", F.getParent());
@@ -1803,16 +1821,15 @@ TEST_F(CGSCCPassManagerTest, TestInsertionOfNewRefSCCMutuallyRecursive) {
18031821

18041822
// Add 'f -> h1' ref edge.
18051823
(void)CastInst::CreatePointerCast(H1, Type::getInt8PtrTy(F.getContext()),
1806-
"h.ref", &F.getEntryBlock().front());
1807-
1808-
CG.addNewFunctionIntoRefSCC(*H1, C.getOuterRefSCC());
1809-
CG.addNewFunctionIntoRefSCC(*H2, C.getOuterRefSCC());
1824+
"h1.ref", &F.getEntryBlock().front());
1825+
// Add 'f -> h2' ref edge.
1826+
(void)CastInst::CreatePointerCast(H2, Type::getInt8PtrTy(F.getContext()),
1827+
"h2.ref", &F.getEntryBlock().front());
18101828

18111829
ASSERT_NO_FATAL_FAILURE(
18121830
updateCGAndAnalysisManagerForCGSCCPass(CG, C, N, AM, UR, FAM))
1813-
<< "Updating the call graph with a demoted, self-referential "
1814-
"call edge 'f -> f', a newly inserted ref edge 'f -> g', and "
1815-
"mutually recursive h1 <-> h2 caused a fatal failure";
1831+
<< "Updating the call graph with mutually recursive g1 <-> g2, h1 "
1832+
"<-> h2 caused a fatal failure";
18161833
}
18171834
}));
18181835

llvm/unittests/Analysis/LazyCallGraphTest.cpp

Lines changed: 0 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -451,47 +451,6 @@ TEST(LazyCallGraphTest, BasicGraphMutation) {
451451
EXPECT_EQ(0, std::distance(B->begin(), B->end()));
452452
}
453453

454-
TEST(LazyCallGraphTest, BasicGraphMutationOutlining) {
455-
LLVMContext Context;
456-
std::unique_ptr<Module> M = parseAssembly(Context, "define void @a() {\n"
457-
"entry:\n"
458-
" call void @b()\n"
459-
" call void @c()\n"
460-
" ret void\n"
461-
"}\n"
462-
"define void @b() {\n"
463-
"entry:\n"
464-
" ret void\n"
465-
"}\n"
466-
"define void @c() {\n"
467-
"entry:\n"
468-
" ret void\n"
469-
"}\n");
470-
LazyCallGraph CG = buildCG(*M);
471-
472-
LazyCallGraph::Node &A = CG.get(lookupFunction(*M, "a"));
473-
LazyCallGraph::Node &B = CG.get(lookupFunction(*M, "b"));
474-
LazyCallGraph::Node &C = CG.get(lookupFunction(*M, "c"));
475-
A.populate();
476-
B.populate();
477-
C.populate();
478-
CG.buildRefSCCs();
479-
480-
// Add a new function that is called from @b and verify it is in the same SCC.
481-
Function &BFn = B.getFunction();
482-
Function *NewFn =
483-
Function::Create(BFn.getFunctionType(), BFn.getLinkage(), "NewFn", *M);
484-
auto IP = BFn.getEntryBlock().getFirstInsertionPt();
485-
CallInst::Create(NewFn, "", &*IP);
486-
CG.addNewFunctionIntoSCC(*NewFn, *CG.lookupSCC(B));
487-
488-
EXPECT_EQ(CG.lookupSCC(A)->size(), 1);
489-
EXPECT_EQ(CG.lookupSCC(B)->size(), 2);
490-
EXPECT_EQ(CG.lookupSCC(C)->size(), 1);
491-
EXPECT_EQ(CG.lookupSCC(*CG.lookup(*NewFn))->size(), 2);
492-
EXPECT_EQ(CG.lookupSCC(*CG.lookup(*NewFn))->size(), CG.lookupSCC(B)->size());
493-
}
494-
495454
TEST(LazyCallGraphTest, InnerSCCFormation) {
496455
LLVMContext Context;
497456
std::unique_ptr<Module> M = parseAssembly(Context, DiamondOfTriangles);
@@ -2211,46 +2170,4 @@ TEST(LazyCallGraphTest, RemoveFunctionWithSpurriousRef) {
22112170
EXPECT_EQ(&RC2, &*I++);
22122171
EXPECT_EQ(CG.postorder_ref_scc_end(), I);
22132172
}
2214-
2215-
TEST(LazyCallGraphTest, AddNewFunctionIntoRefSCC) {
2216-
LLVMContext Context;
2217-
// Build and populate a graph composed of a single, self-referential node.
2218-
std::unique_ptr<Module> M = parseAssembly(Context, "define void @f() {\n"
2219-
"entry:\n"
2220-
" call void @f()\n"
2221-
" ret void\n"
2222-
"}\n");
2223-
LazyCallGraph CG = buildCG(*M);
2224-
CG.buildRefSCCs();
2225-
2226-
// At this point 'f' is in the call graph.
2227-
auto &F = lookupFunction(*M, "f");
2228-
LazyCallGraph::Node *FN = CG.lookup(F);
2229-
EXPECT_NE(FN, nullptr);
2230-
2231-
// And it has an SCC, of course.
2232-
auto *FSCC = CG.lookupSCC(*FN);
2233-
EXPECT_NE(FSCC, nullptr);
2234-
2235-
// Now, create a new function 'g'.
2236-
auto *G = Function::Create(F.getFunctionType(), F.getLinkage(),
2237-
F.getAddressSpace(), "g", F.getParent());
2238-
BasicBlock::Create(F.getParent()->getContext(), "entry", G);
2239-
2240-
// Instruct the LazyCallGraph to create a new node for 'g', within the same
2241-
// RefSCC as 'f', but in a separate SCC.
2242-
CG.addNewFunctionIntoRefSCC(*G, FSCC->getOuterRefSCC());
2243-
2244-
// 'g' should now be in the call graph.
2245-
LazyCallGraph::Node *GN = CG.lookup(*G);
2246-
EXPECT_NE(GN, nullptr);
2247-
// 'g' should have an SCC, composed of the singular node 'g'.
2248-
// ('f' should not be included in the 'g' SCC.)
2249-
LazyCallGraph::SCC *GSCC = CG.lookupSCC(*GN);
2250-
EXPECT_NE(GSCC, nullptr);
2251-
EXPECT_EQ(GSCC->size(), 1);
2252-
EXPECT_NE(GSCC, FSCC);
2253-
// 'g' and 'f' should be part of the same RefSCC.
2254-
EXPECT_EQ(&GSCC->getOuterRefSCC(), &FSCC->getOuterRefSCC());
2255-
}
22562173
}

0 commit comments

Comments
 (0)