LazyCallGraphTest.cpp 77 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071
  1. //===- LazyCallGraphTest.cpp - Unit tests for the lazy CG analysis --------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "llvm/Analysis/LazyCallGraph.h"
  10. #include "llvm/AsmParser/Parser.h"
  11. #include "llvm/IR/Function.h"
  12. #include "llvm/IR/Instructions.h"
  13. #include "llvm/IR/LLVMContext.h"
  14. #include "llvm/IR/Module.h"
  15. #include "llvm/Support/ErrorHandling.h"
  16. #include "llvm/Support/SourceMgr.h"
  17. #include "gtest/gtest.h"
  18. #include <memory>
  19. using namespace llvm;
  20. namespace {
  21. std::unique_ptr<Module> parseAssembly(LLVMContext &Context,
  22. const char *Assembly) {
  23. SMDiagnostic Error;
  24. std::unique_ptr<Module> M = parseAssemblyString(Assembly, Error, Context);
  25. std::string ErrMsg;
  26. raw_string_ostream OS(ErrMsg);
  27. Error.print("", OS);
  28. // A failure here means that the test itself is buggy.
  29. if (!M)
  30. report_fatal_error(OS.str().c_str());
  31. return M;
  32. }
  33. /*
  34. IR forming a call graph with a diamond of triangle-shaped SCCs:
  35. d1
  36. / \
  37. d3--d2
  38. / \
  39. b1 c1
  40. / \ / \
  41. b3--b2 c3--c2
  42. \ /
  43. a1
  44. / \
  45. a3--a2
  46. All call edges go up between SCCs, and clockwise around the SCC.
  47. */
  48. static const char DiamondOfTriangles[] =
  49. "define void @a1() {\n"
  50. "entry:\n"
  51. " call void @a2()\n"
  52. " call void @b2()\n"
  53. " call void @c3()\n"
  54. " ret void\n"
  55. "}\n"
  56. "define void @a2() {\n"
  57. "entry:\n"
  58. " call void @a3()\n"
  59. " ret void\n"
  60. "}\n"
  61. "define void @a3() {\n"
  62. "entry:\n"
  63. " call void @a1()\n"
  64. " ret void\n"
  65. "}\n"
  66. "define void @b1() {\n"
  67. "entry:\n"
  68. " call void @b2()\n"
  69. " call void @d3()\n"
  70. " ret void\n"
  71. "}\n"
  72. "define void @b2() {\n"
  73. "entry:\n"
  74. " call void @b3()\n"
  75. " ret void\n"
  76. "}\n"
  77. "define void @b3() {\n"
  78. "entry:\n"
  79. " call void @b1()\n"
  80. " ret void\n"
  81. "}\n"
  82. "define void @c1() {\n"
  83. "entry:\n"
  84. " call void @c2()\n"
  85. " call void @d2()\n"
  86. " ret void\n"
  87. "}\n"
  88. "define void @c2() {\n"
  89. "entry:\n"
  90. " call void @c3()\n"
  91. " ret void\n"
  92. "}\n"
  93. "define void @c3() {\n"
  94. "entry:\n"
  95. " call void @c1()\n"
  96. " ret void\n"
  97. "}\n"
  98. "define void @d1() {\n"
  99. "entry:\n"
  100. " call void @d2()\n"
  101. " ret void\n"
  102. "}\n"
  103. "define void @d2() {\n"
  104. "entry:\n"
  105. " call void @d3()\n"
  106. " ret void\n"
  107. "}\n"
  108. "define void @d3() {\n"
  109. "entry:\n"
  110. " call void @d1()\n"
  111. " ret void\n"
  112. "}\n";
  113. /*
  114. IR forming a reference graph with a diamond of triangle-shaped RefSCCs
  115. d1
  116. / \
  117. d3--d2
  118. / \
  119. b1 c1
  120. / \ / \
  121. b3--b2 c3--c2
  122. \ /
  123. a1
  124. / \
  125. a3--a2
  126. All call edges go up between RefSCCs, and clockwise around the RefSCC.
  127. */
  128. static const char DiamondOfTrianglesRefGraph[] =
  129. "define void @a1() {\n"
  130. "entry:\n"
  131. " %a = alloca void ()*\n"
  132. " store void ()* @a2, void ()** %a\n"
  133. " store void ()* @b2, void ()** %a\n"
  134. " store void ()* @c3, void ()** %a\n"
  135. " ret void\n"
  136. "}\n"
  137. "define void @a2() {\n"
  138. "entry:\n"
  139. " %a = alloca void ()*\n"
  140. " store void ()* @a3, void ()** %a\n"
  141. " ret void\n"
  142. "}\n"
  143. "define void @a3() {\n"
  144. "entry:\n"
  145. " %a = alloca void ()*\n"
  146. " store void ()* @a1, void ()** %a\n"
  147. " ret void\n"
  148. "}\n"
  149. "define void @b1() {\n"
  150. "entry:\n"
  151. " %a = alloca void ()*\n"
  152. " store void ()* @b2, void ()** %a\n"
  153. " store void ()* @d3, void ()** %a\n"
  154. " ret void\n"
  155. "}\n"
  156. "define void @b2() {\n"
  157. "entry:\n"
  158. " %a = alloca void ()*\n"
  159. " store void ()* @b3, void ()** %a\n"
  160. " ret void\n"
  161. "}\n"
  162. "define void @b3() {\n"
  163. "entry:\n"
  164. " %a = alloca void ()*\n"
  165. " store void ()* @b1, void ()** %a\n"
  166. " ret void\n"
  167. "}\n"
  168. "define void @c1() {\n"
  169. "entry:\n"
  170. " %a = alloca void ()*\n"
  171. " store void ()* @c2, void ()** %a\n"
  172. " store void ()* @d2, void ()** %a\n"
  173. " ret void\n"
  174. "}\n"
  175. "define void @c2() {\n"
  176. "entry:\n"
  177. " %a = alloca void ()*\n"
  178. " store void ()* @c3, void ()** %a\n"
  179. " ret void\n"
  180. "}\n"
  181. "define void @c3() {\n"
  182. "entry:\n"
  183. " %a = alloca void ()*\n"
  184. " store void ()* @c1, void ()** %a\n"
  185. " ret void\n"
  186. "}\n"
  187. "define void @d1() {\n"
  188. "entry:\n"
  189. " %a = alloca void ()*\n"
  190. " store void ()* @d2, void ()** %a\n"
  191. " ret void\n"
  192. "}\n"
  193. "define void @d2() {\n"
  194. "entry:\n"
  195. " %a = alloca void ()*\n"
  196. " store void ()* @d3, void ()** %a\n"
  197. " ret void\n"
  198. "}\n"
  199. "define void @d3() {\n"
  200. "entry:\n"
  201. " %a = alloca void ()*\n"
  202. " store void ()* @d1, void ()** %a\n"
  203. " ret void\n"
  204. "}\n";
  205. static LazyCallGraph buildCG(Module &M) {
  206. TargetLibraryInfoImpl TLII(Triple(M.getTargetTriple()));
  207. TargetLibraryInfo TLI(TLII);
  208. LazyCallGraph CG(M, TLI);
  209. return CG;
  210. }
  211. TEST(LazyCallGraphTest, BasicGraphFormation) {
  212. LLVMContext Context;
  213. std::unique_ptr<Module> M = parseAssembly(Context, DiamondOfTriangles);
  214. LazyCallGraph CG = buildCG(*M);
  215. // The order of the entry nodes should be stable w.r.t. the source order of
  216. // the IR, and everything in our module is an entry node, so just directly
  217. // build variables for each node.
  218. auto I = CG.begin();
  219. LazyCallGraph::Node &A1 = (I++)->getNode();
  220. EXPECT_EQ("a1", A1.getFunction().getName());
  221. LazyCallGraph::Node &A2 = (I++)->getNode();
  222. EXPECT_EQ("a2", A2.getFunction().getName());
  223. LazyCallGraph::Node &A3 = (I++)->getNode();
  224. EXPECT_EQ("a3", A3.getFunction().getName());
  225. LazyCallGraph::Node &B1 = (I++)->getNode();
  226. EXPECT_EQ("b1", B1.getFunction().getName());
  227. LazyCallGraph::Node &B2 = (I++)->getNode();
  228. EXPECT_EQ("b2", B2.getFunction().getName());
  229. LazyCallGraph::Node &B3 = (I++)->getNode();
  230. EXPECT_EQ("b3", B3.getFunction().getName());
  231. LazyCallGraph::Node &C1 = (I++)->getNode();
  232. EXPECT_EQ("c1", C1.getFunction().getName());
  233. LazyCallGraph::Node &C2 = (I++)->getNode();
  234. EXPECT_EQ("c2", C2.getFunction().getName());
  235. LazyCallGraph::Node &C3 = (I++)->getNode();
  236. EXPECT_EQ("c3", C3.getFunction().getName());
  237. LazyCallGraph::Node &D1 = (I++)->getNode();
  238. EXPECT_EQ("d1", D1.getFunction().getName());
  239. LazyCallGraph::Node &D2 = (I++)->getNode();
  240. EXPECT_EQ("d2", D2.getFunction().getName());
  241. LazyCallGraph::Node &D3 = (I++)->getNode();
  242. EXPECT_EQ("d3", D3.getFunction().getName());
  243. EXPECT_EQ(CG.end(), I);
  244. // Build vectors and sort them for the rest of the assertions to make them
  245. // independent of order.
  246. std::vector<std::string> Nodes;
  247. for (LazyCallGraph::Edge &E : A1.populate())
  248. Nodes.push_back(E.getFunction().getName());
  249. std::sort(Nodes.begin(), Nodes.end());
  250. EXPECT_EQ("a2", Nodes[0]);
  251. EXPECT_EQ("b2", Nodes[1]);
  252. EXPECT_EQ("c3", Nodes[2]);
  253. Nodes.clear();
  254. A2.populate();
  255. EXPECT_EQ(A2->end(), std::next(A2->begin()));
  256. EXPECT_EQ("a3", A2->begin()->getFunction().getName());
  257. A3.populate();
  258. EXPECT_EQ(A3->end(), std::next(A3->begin()));
  259. EXPECT_EQ("a1", A3->begin()->getFunction().getName());
  260. for (LazyCallGraph::Edge &E : B1.populate())
  261. Nodes.push_back(E.getFunction().getName());
  262. std::sort(Nodes.begin(), Nodes.end());
  263. EXPECT_EQ("b2", Nodes[0]);
  264. EXPECT_EQ("d3", Nodes[1]);
  265. Nodes.clear();
  266. B2.populate();
  267. EXPECT_EQ(B2->end(), std::next(B2->begin()));
  268. EXPECT_EQ("b3", B2->begin()->getFunction().getName());
  269. B3.populate();
  270. EXPECT_EQ(B3->end(), std::next(B3->begin()));
  271. EXPECT_EQ("b1", B3->begin()->getFunction().getName());
  272. for (LazyCallGraph::Edge &E : C1.populate())
  273. Nodes.push_back(E.getFunction().getName());
  274. std::sort(Nodes.begin(), Nodes.end());
  275. EXPECT_EQ("c2", Nodes[0]);
  276. EXPECT_EQ("d2", Nodes[1]);
  277. Nodes.clear();
  278. C2.populate();
  279. EXPECT_EQ(C2->end(), std::next(C2->begin()));
  280. EXPECT_EQ("c3", C2->begin()->getFunction().getName());
  281. C3.populate();
  282. EXPECT_EQ(C3->end(), std::next(C3->begin()));
  283. EXPECT_EQ("c1", C3->begin()->getFunction().getName());
  284. D1.populate();
  285. EXPECT_EQ(D1->end(), std::next(D1->begin()));
  286. EXPECT_EQ("d2", D1->begin()->getFunction().getName());
  287. D2.populate();
  288. EXPECT_EQ(D2->end(), std::next(D2->begin()));
  289. EXPECT_EQ("d3", D2->begin()->getFunction().getName());
  290. D3.populate();
  291. EXPECT_EQ(D3->end(), std::next(D3->begin()));
  292. EXPECT_EQ("d1", D3->begin()->getFunction().getName());
  293. // Now lets look at the RefSCCs and SCCs.
  294. CG.buildRefSCCs();
  295. auto J = CG.postorder_ref_scc_begin();
  296. LazyCallGraph::RefSCC &D = *J++;
  297. ASSERT_EQ(1, D.size());
  298. for (LazyCallGraph::Node &N : *D.begin())
  299. Nodes.push_back(N.getFunction().getName());
  300. std::sort(Nodes.begin(), Nodes.end());
  301. EXPECT_EQ(3u, Nodes.size());
  302. EXPECT_EQ("d1", Nodes[0]);
  303. EXPECT_EQ("d2", Nodes[1]);
  304. EXPECT_EQ("d3", Nodes[2]);
  305. Nodes.clear();
  306. EXPECT_FALSE(D.isParentOf(D));
  307. EXPECT_FALSE(D.isChildOf(D));
  308. EXPECT_FALSE(D.isAncestorOf(D));
  309. EXPECT_FALSE(D.isDescendantOf(D));
  310. EXPECT_EQ(&D, &*CG.postorder_ref_scc_begin());
  311. LazyCallGraph::RefSCC &C = *J++;
  312. ASSERT_EQ(1, C.size());
  313. for (LazyCallGraph::Node &N : *C.begin())
  314. Nodes.push_back(N.getFunction().getName());
  315. std::sort(Nodes.begin(), Nodes.end());
  316. EXPECT_EQ(3u, Nodes.size());
  317. EXPECT_EQ("c1", Nodes[0]);
  318. EXPECT_EQ("c2", Nodes[1]);
  319. EXPECT_EQ("c3", Nodes[2]);
  320. Nodes.clear();
  321. EXPECT_TRUE(C.isParentOf(D));
  322. EXPECT_FALSE(C.isChildOf(D));
  323. EXPECT_TRUE(C.isAncestorOf(D));
  324. EXPECT_FALSE(C.isDescendantOf(D));
  325. EXPECT_EQ(&C, &*std::next(CG.postorder_ref_scc_begin()));
  326. LazyCallGraph::RefSCC &B = *J++;
  327. ASSERT_EQ(1, B.size());
  328. for (LazyCallGraph::Node &N : *B.begin())
  329. Nodes.push_back(N.getFunction().getName());
  330. std::sort(Nodes.begin(), Nodes.end());
  331. EXPECT_EQ(3u, Nodes.size());
  332. EXPECT_EQ("b1", Nodes[0]);
  333. EXPECT_EQ("b2", Nodes[1]);
  334. EXPECT_EQ("b3", Nodes[2]);
  335. Nodes.clear();
  336. EXPECT_TRUE(B.isParentOf(D));
  337. EXPECT_FALSE(B.isChildOf(D));
  338. EXPECT_TRUE(B.isAncestorOf(D));
  339. EXPECT_FALSE(B.isDescendantOf(D));
  340. EXPECT_FALSE(B.isAncestorOf(C));
  341. EXPECT_FALSE(C.isAncestorOf(B));
  342. EXPECT_EQ(&B, &*std::next(CG.postorder_ref_scc_begin(), 2));
  343. LazyCallGraph::RefSCC &A = *J++;
  344. ASSERT_EQ(1, A.size());
  345. for (LazyCallGraph::Node &N : *A.begin())
  346. Nodes.push_back(N.getFunction().getName());
  347. std::sort(Nodes.begin(), Nodes.end());
  348. EXPECT_EQ(3u, Nodes.size());
  349. EXPECT_EQ("a1", Nodes[0]);
  350. EXPECT_EQ("a2", Nodes[1]);
  351. EXPECT_EQ("a3", Nodes[2]);
  352. Nodes.clear();
  353. EXPECT_TRUE(A.isParentOf(B));
  354. EXPECT_TRUE(A.isParentOf(C));
  355. EXPECT_FALSE(A.isParentOf(D));
  356. EXPECT_TRUE(A.isAncestorOf(B));
  357. EXPECT_TRUE(A.isAncestorOf(C));
  358. EXPECT_TRUE(A.isAncestorOf(D));
  359. EXPECT_EQ(&A, &*std::next(CG.postorder_ref_scc_begin(), 3));
  360. EXPECT_EQ(CG.postorder_ref_scc_end(), J);
  361. EXPECT_EQ(J, std::next(CG.postorder_ref_scc_begin(), 4));
  362. }
  363. static Function &lookupFunction(Module &M, StringRef Name) {
  364. for (Function &F : M)
  365. if (F.getName() == Name)
  366. return F;
  367. report_fatal_error("Couldn't find function!");
  368. }
  369. TEST(LazyCallGraphTest, BasicGraphMutation) {
  370. LLVMContext Context;
  371. std::unique_ptr<Module> M = parseAssembly(Context, "define void @a() {\n"
  372. "entry:\n"
  373. " call void @b()\n"
  374. " call void @c()\n"
  375. " ret void\n"
  376. "}\n"
  377. "define void @b() {\n"
  378. "entry:\n"
  379. " ret void\n"
  380. "}\n"
  381. "define void @c() {\n"
  382. "entry:\n"
  383. " ret void\n"
  384. "}\n");
  385. LazyCallGraph CG = buildCG(*M);
  386. LazyCallGraph::Node &A = CG.get(lookupFunction(*M, "a"));
  387. LazyCallGraph::Node &B = CG.get(lookupFunction(*M, "b"));
  388. A.populate();
  389. EXPECT_EQ(2, std::distance(A->begin(), A->end()));
  390. B.populate();
  391. EXPECT_EQ(0, std::distance(B->begin(), B->end()));
  392. LazyCallGraph::Node &C = CG.get(lookupFunction(*M, "c"));
  393. C.populate();
  394. CG.insertEdge(B, C, LazyCallGraph::Edge::Call);
  395. EXPECT_EQ(1, std::distance(B->begin(), B->end()));
  396. EXPECT_EQ(0, std::distance(C->begin(), C->end()));
  397. CG.insertEdge(C, B, LazyCallGraph::Edge::Call);
  398. EXPECT_EQ(1, std::distance(C->begin(), C->end()));
  399. EXPECT_EQ(&B, &C->begin()->getNode());
  400. CG.insertEdge(C, C, LazyCallGraph::Edge::Call);
  401. EXPECT_EQ(2, std::distance(C->begin(), C->end()));
  402. EXPECT_EQ(&B, &C->begin()->getNode());
  403. EXPECT_EQ(&C, &std::next(C->begin())->getNode());
  404. CG.removeEdge(C, B);
  405. EXPECT_EQ(1, std::distance(C->begin(), C->end()));
  406. EXPECT_EQ(&C, &C->begin()->getNode());
  407. CG.removeEdge(C, C);
  408. EXPECT_EQ(0, std::distance(C->begin(), C->end()));
  409. CG.removeEdge(B, C);
  410. EXPECT_EQ(0, std::distance(B->begin(), B->end()));
  411. }
  412. TEST(LazyCallGraphTest, InnerSCCFormation) {
  413. LLVMContext Context;
  414. std::unique_ptr<Module> M = parseAssembly(Context, DiamondOfTriangles);
  415. LazyCallGraph CG = buildCG(*M);
  416. // Now mutate the graph to connect every node into a single RefSCC to ensure
  417. // that our inner SCC formation handles the rest.
  418. LazyCallGraph::Node &D1 = CG.get(lookupFunction(*M, "d1"));
  419. LazyCallGraph::Node &A1 = CG.get(lookupFunction(*M, "a1"));
  420. A1.populate();
  421. D1.populate();
  422. CG.insertEdge(D1, A1, LazyCallGraph::Edge::Ref);
  423. // Build vectors and sort them for the rest of the assertions to make them
  424. // independent of order.
  425. std::vector<std::string> Nodes;
  426. // We should build a single RefSCC for the entire graph.
  427. CG.buildRefSCCs();
  428. auto I = CG.postorder_ref_scc_begin();
  429. LazyCallGraph::RefSCC &RC = *I++;
  430. EXPECT_EQ(CG.postorder_ref_scc_end(), I);
  431. // Now walk the four SCCs which should be in post-order.
  432. auto J = RC.begin();
  433. LazyCallGraph::SCC &D = *J++;
  434. for (LazyCallGraph::Node &N : D)
  435. Nodes.push_back(N.getFunction().getName());
  436. std::sort(Nodes.begin(), Nodes.end());
  437. EXPECT_EQ(3u, Nodes.size());
  438. EXPECT_EQ("d1", Nodes[0]);
  439. EXPECT_EQ("d2", Nodes[1]);
  440. EXPECT_EQ("d3", Nodes[2]);
  441. Nodes.clear();
  442. LazyCallGraph::SCC &B = *J++;
  443. for (LazyCallGraph::Node &N : B)
  444. Nodes.push_back(N.getFunction().getName());
  445. std::sort(Nodes.begin(), Nodes.end());
  446. EXPECT_EQ(3u, Nodes.size());
  447. EXPECT_EQ("b1", Nodes[0]);
  448. EXPECT_EQ("b2", Nodes[1]);
  449. EXPECT_EQ("b3", Nodes[2]);
  450. Nodes.clear();
  451. LazyCallGraph::SCC &C = *J++;
  452. for (LazyCallGraph::Node &N : C)
  453. Nodes.push_back(N.getFunction().getName());
  454. std::sort(Nodes.begin(), Nodes.end());
  455. EXPECT_EQ(3u, Nodes.size());
  456. EXPECT_EQ("c1", Nodes[0]);
  457. EXPECT_EQ("c2", Nodes[1]);
  458. EXPECT_EQ("c3", Nodes[2]);
  459. Nodes.clear();
  460. LazyCallGraph::SCC &A = *J++;
  461. for (LazyCallGraph::Node &N : A)
  462. Nodes.push_back(N.getFunction().getName());
  463. std::sort(Nodes.begin(), Nodes.end());
  464. EXPECT_EQ(3u, Nodes.size());
  465. EXPECT_EQ("a1", Nodes[0]);
  466. EXPECT_EQ("a2", Nodes[1]);
  467. EXPECT_EQ("a3", Nodes[2]);
  468. Nodes.clear();
  469. EXPECT_EQ(RC.end(), J);
  470. }
  471. TEST(LazyCallGraphTest, MultiArmSCC) {
  472. LLVMContext Context;
  473. // Two interlocking cycles. The really useful thing about this SCC is that it
  474. // will require Tarjan's DFS to backtrack and finish processing all of the
  475. // children of each node in the SCC. Since this involves call edges, both
  476. // Tarjan implementations will have to successfully navigate the structure.
  477. std::unique_ptr<Module> M = parseAssembly(Context, "define void @f1() {\n"
  478. "entry:\n"
  479. " call void @f2()\n"
  480. " call void @f4()\n"
  481. " ret void\n"
  482. "}\n"
  483. "define void @f2() {\n"
  484. "entry:\n"
  485. " call void @f3()\n"
  486. " ret void\n"
  487. "}\n"
  488. "define void @f3() {\n"
  489. "entry:\n"
  490. " call void @f1()\n"
  491. " ret void\n"
  492. "}\n"
  493. "define void @f4() {\n"
  494. "entry:\n"
  495. " call void @f5()\n"
  496. " ret void\n"
  497. "}\n"
  498. "define void @f5() {\n"
  499. "entry:\n"
  500. " call void @f1()\n"
  501. " ret void\n"
  502. "}\n");
  503. LazyCallGraph CG = buildCG(*M);
  504. // Force the graph to be fully expanded.
  505. CG.buildRefSCCs();
  506. auto I = CG.postorder_ref_scc_begin();
  507. LazyCallGraph::RefSCC &RC = *I++;
  508. EXPECT_EQ(CG.postorder_ref_scc_end(), I);
  509. LazyCallGraph::Node &N1 = *CG.lookup(lookupFunction(*M, "f1"));
  510. LazyCallGraph::Node &N2 = *CG.lookup(lookupFunction(*M, "f2"));
  511. LazyCallGraph::Node &N3 = *CG.lookup(lookupFunction(*M, "f3"));
  512. LazyCallGraph::Node &N4 = *CG.lookup(lookupFunction(*M, "f4"));
  513. LazyCallGraph::Node &N5 = *CG.lookup(lookupFunction(*M, "f4"));
  514. EXPECT_EQ(&RC, CG.lookupRefSCC(N1));
  515. EXPECT_EQ(&RC, CG.lookupRefSCC(N2));
  516. EXPECT_EQ(&RC, CG.lookupRefSCC(N3));
  517. EXPECT_EQ(&RC, CG.lookupRefSCC(N4));
  518. EXPECT_EQ(&RC, CG.lookupRefSCC(N5));
  519. ASSERT_EQ(1, RC.size());
  520. LazyCallGraph::SCC &C = *RC.begin();
  521. EXPECT_EQ(&C, CG.lookupSCC(N1));
  522. EXPECT_EQ(&C, CG.lookupSCC(N2));
  523. EXPECT_EQ(&C, CG.lookupSCC(N3));
  524. EXPECT_EQ(&C, CG.lookupSCC(N4));
  525. EXPECT_EQ(&C, CG.lookupSCC(N5));
  526. }
  527. TEST(LazyCallGraphTest, OutgoingEdgeMutation) {
  528. LLVMContext Context;
  529. std::unique_ptr<Module> M = parseAssembly(Context, "define void @a() {\n"
  530. "entry:\n"
  531. " call void @b()\n"
  532. " call void @c()\n"
  533. " ret void\n"
  534. "}\n"
  535. "define void @b() {\n"
  536. "entry:\n"
  537. " call void @d()\n"
  538. " ret void\n"
  539. "}\n"
  540. "define void @c() {\n"
  541. "entry:\n"
  542. " call void @d()\n"
  543. " ret void\n"
  544. "}\n"
  545. "define void @d() {\n"
  546. "entry:\n"
  547. " ret void\n"
  548. "}\n");
  549. LazyCallGraph CG = buildCG(*M);
  550. // Force the graph to be fully expanded.
  551. CG.buildRefSCCs();
  552. for (LazyCallGraph::RefSCC &RC : CG.postorder_ref_sccs())
  553. dbgs() << "Formed RefSCC: " << RC << "\n";
  554. LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
  555. LazyCallGraph::Node &B = *CG.lookup(lookupFunction(*M, "b"));
  556. LazyCallGraph::Node &C = *CG.lookup(lookupFunction(*M, "c"));
  557. LazyCallGraph::Node &D = *CG.lookup(lookupFunction(*M, "d"));
  558. LazyCallGraph::SCC &AC = *CG.lookupSCC(A);
  559. LazyCallGraph::SCC &BC = *CG.lookupSCC(B);
  560. LazyCallGraph::SCC &CC = *CG.lookupSCC(C);
  561. LazyCallGraph::SCC &DC = *CG.lookupSCC(D);
  562. LazyCallGraph::RefSCC &ARC = *CG.lookupRefSCC(A);
  563. LazyCallGraph::RefSCC &BRC = *CG.lookupRefSCC(B);
  564. LazyCallGraph::RefSCC &CRC = *CG.lookupRefSCC(C);
  565. LazyCallGraph::RefSCC &DRC = *CG.lookupRefSCC(D);
  566. EXPECT_TRUE(ARC.isParentOf(BRC));
  567. EXPECT_TRUE(AC.isParentOf(BC));
  568. EXPECT_TRUE(ARC.isParentOf(CRC));
  569. EXPECT_TRUE(AC.isParentOf(CC));
  570. EXPECT_FALSE(ARC.isParentOf(DRC));
  571. EXPECT_FALSE(AC.isParentOf(DC));
  572. EXPECT_TRUE(ARC.isAncestorOf(DRC));
  573. EXPECT_TRUE(AC.isAncestorOf(DC));
  574. EXPECT_FALSE(DRC.isChildOf(ARC));
  575. EXPECT_FALSE(DC.isChildOf(AC));
  576. EXPECT_TRUE(DRC.isDescendantOf(ARC));
  577. EXPECT_TRUE(DC.isDescendantOf(AC));
  578. EXPECT_TRUE(DRC.isChildOf(BRC));
  579. EXPECT_TRUE(DC.isChildOf(BC));
  580. EXPECT_TRUE(DRC.isChildOf(CRC));
  581. EXPECT_TRUE(DC.isChildOf(CC));
  582. EXPECT_EQ(2, std::distance(A->begin(), A->end()));
  583. ARC.insertOutgoingEdge(A, D, LazyCallGraph::Edge::Call);
  584. EXPECT_EQ(3, std::distance(A->begin(), A->end()));
  585. const LazyCallGraph::Edge &NewE = (*A)[D];
  586. EXPECT_TRUE(NewE);
  587. EXPECT_TRUE(NewE.isCall());
  588. EXPECT_EQ(&D, &NewE.getNode());
  589. // Only the parent and child tests sholud have changed. The rest of the graph
  590. // remains the same.
  591. EXPECT_TRUE(ARC.isParentOf(DRC));
  592. EXPECT_TRUE(AC.isParentOf(DC));
  593. EXPECT_TRUE(ARC.isAncestorOf(DRC));
  594. EXPECT_TRUE(AC.isAncestorOf(DC));
  595. EXPECT_TRUE(DRC.isChildOf(ARC));
  596. EXPECT_TRUE(DC.isChildOf(AC));
  597. EXPECT_TRUE(DRC.isDescendantOf(ARC));
  598. EXPECT_TRUE(DC.isDescendantOf(AC));
  599. EXPECT_EQ(&AC, CG.lookupSCC(A));
  600. EXPECT_EQ(&BC, CG.lookupSCC(B));
  601. EXPECT_EQ(&CC, CG.lookupSCC(C));
  602. EXPECT_EQ(&DC, CG.lookupSCC(D));
  603. EXPECT_EQ(&ARC, CG.lookupRefSCC(A));
  604. EXPECT_EQ(&BRC, CG.lookupRefSCC(B));
  605. EXPECT_EQ(&CRC, CG.lookupRefSCC(C));
  606. EXPECT_EQ(&DRC, CG.lookupRefSCC(D));
  607. ARC.switchOutgoingEdgeToRef(A, D);
  608. EXPECT_FALSE(NewE.isCall());
  609. // Verify the reference graph remains the same but the SCC graph is updated.
  610. EXPECT_TRUE(ARC.isParentOf(DRC));
  611. EXPECT_FALSE(AC.isParentOf(DC));
  612. EXPECT_TRUE(ARC.isAncestorOf(DRC));
  613. EXPECT_TRUE(AC.isAncestorOf(DC));
  614. EXPECT_TRUE(DRC.isChildOf(ARC));
  615. EXPECT_FALSE(DC.isChildOf(AC));
  616. EXPECT_TRUE(DRC.isDescendantOf(ARC));
  617. EXPECT_TRUE(DC.isDescendantOf(AC));
  618. EXPECT_EQ(&AC, CG.lookupSCC(A));
  619. EXPECT_EQ(&BC, CG.lookupSCC(B));
  620. EXPECT_EQ(&CC, CG.lookupSCC(C));
  621. EXPECT_EQ(&DC, CG.lookupSCC(D));
  622. EXPECT_EQ(&ARC, CG.lookupRefSCC(A));
  623. EXPECT_EQ(&BRC, CG.lookupRefSCC(B));
  624. EXPECT_EQ(&CRC, CG.lookupRefSCC(C));
  625. EXPECT_EQ(&DRC, CG.lookupRefSCC(D));
  626. ARC.switchOutgoingEdgeToCall(A, D);
  627. EXPECT_TRUE(NewE.isCall());
  628. // Verify the reference graph remains the same but the SCC graph is updated.
  629. EXPECT_TRUE(ARC.isParentOf(DRC));
  630. EXPECT_TRUE(AC.isParentOf(DC));
  631. EXPECT_TRUE(ARC.isAncestorOf(DRC));
  632. EXPECT_TRUE(AC.isAncestorOf(DC));
  633. EXPECT_TRUE(DRC.isChildOf(ARC));
  634. EXPECT_TRUE(DC.isChildOf(AC));
  635. EXPECT_TRUE(DRC.isDescendantOf(ARC));
  636. EXPECT_TRUE(DC.isDescendantOf(AC));
  637. EXPECT_EQ(&AC, CG.lookupSCC(A));
  638. EXPECT_EQ(&BC, CG.lookupSCC(B));
  639. EXPECT_EQ(&CC, CG.lookupSCC(C));
  640. EXPECT_EQ(&DC, CG.lookupSCC(D));
  641. EXPECT_EQ(&ARC, CG.lookupRefSCC(A));
  642. EXPECT_EQ(&BRC, CG.lookupRefSCC(B));
  643. EXPECT_EQ(&CRC, CG.lookupRefSCC(C));
  644. EXPECT_EQ(&DRC, CG.lookupRefSCC(D));
  645. ARC.removeOutgoingEdge(A, D);
  646. EXPECT_EQ(2, std::distance(A->begin(), A->end()));
  647. // Now the parent and child tests fail again but the rest remains the same.
  648. EXPECT_FALSE(ARC.isParentOf(DRC));
  649. EXPECT_FALSE(AC.isParentOf(DC));
  650. EXPECT_TRUE(ARC.isAncestorOf(DRC));
  651. EXPECT_TRUE(AC.isAncestorOf(DC));
  652. EXPECT_FALSE(DRC.isChildOf(ARC));
  653. EXPECT_FALSE(DC.isChildOf(AC));
  654. EXPECT_TRUE(DRC.isDescendantOf(ARC));
  655. EXPECT_TRUE(DC.isDescendantOf(AC));
  656. EXPECT_EQ(&AC, CG.lookupSCC(A));
  657. EXPECT_EQ(&BC, CG.lookupSCC(B));
  658. EXPECT_EQ(&CC, CG.lookupSCC(C));
  659. EXPECT_EQ(&DC, CG.lookupSCC(D));
  660. EXPECT_EQ(&ARC, CG.lookupRefSCC(A));
  661. EXPECT_EQ(&BRC, CG.lookupRefSCC(B));
  662. EXPECT_EQ(&CRC, CG.lookupRefSCC(C));
  663. EXPECT_EQ(&DRC, CG.lookupRefSCC(D));
  664. }
  665. TEST(LazyCallGraphTest, IncomingEdgeInsertion) {
  666. LLVMContext Context;
  667. // We want to ensure we can add edges even across complex diamond graphs, so
  668. // we use the diamond of triangles graph defined above. The ascii diagram is
  669. // repeated here for easy reference.
  670. //
  671. // d1 |
  672. // / \ |
  673. // d3--d2 |
  674. // / \ |
  675. // b1 c1 |
  676. // / \ / \ |
  677. // b3--b2 c3--c2 |
  678. // \ / |
  679. // a1 |
  680. // / \ |
  681. // a3--a2 |
  682. //
  683. std::unique_ptr<Module> M = parseAssembly(Context, DiamondOfTriangles);
  684. LazyCallGraph CG = buildCG(*M);
  685. // Force the graph to be fully expanded.
  686. CG.buildRefSCCs();
  687. for (LazyCallGraph::RefSCC &RC : CG.postorder_ref_sccs())
  688. dbgs() << "Formed RefSCC: " << RC << "\n";
  689. LazyCallGraph::Node &A1 = *CG.lookup(lookupFunction(*M, "a1"));
  690. LazyCallGraph::Node &A2 = *CG.lookup(lookupFunction(*M, "a2"));
  691. LazyCallGraph::Node &A3 = *CG.lookup(lookupFunction(*M, "a3"));
  692. LazyCallGraph::Node &B1 = *CG.lookup(lookupFunction(*M, "b1"));
  693. LazyCallGraph::Node &B2 = *CG.lookup(lookupFunction(*M, "b2"));
  694. LazyCallGraph::Node &B3 = *CG.lookup(lookupFunction(*M, "b3"));
  695. LazyCallGraph::Node &C1 = *CG.lookup(lookupFunction(*M, "c1"));
  696. LazyCallGraph::Node &C2 = *CG.lookup(lookupFunction(*M, "c2"));
  697. LazyCallGraph::Node &C3 = *CG.lookup(lookupFunction(*M, "c3"));
  698. LazyCallGraph::Node &D1 = *CG.lookup(lookupFunction(*M, "d1"));
  699. LazyCallGraph::Node &D2 = *CG.lookup(lookupFunction(*M, "d2"));
  700. LazyCallGraph::Node &D3 = *CG.lookup(lookupFunction(*M, "d3"));
  701. LazyCallGraph::RefSCC &ARC = *CG.lookupRefSCC(A1);
  702. LazyCallGraph::RefSCC &BRC = *CG.lookupRefSCC(B1);
  703. LazyCallGraph::RefSCC &CRC = *CG.lookupRefSCC(C1);
  704. LazyCallGraph::RefSCC &DRC = *CG.lookupRefSCC(D1);
  705. ASSERT_EQ(&ARC, CG.lookupRefSCC(A2));
  706. ASSERT_EQ(&ARC, CG.lookupRefSCC(A3));
  707. ASSERT_EQ(&BRC, CG.lookupRefSCC(B2));
  708. ASSERT_EQ(&BRC, CG.lookupRefSCC(B3));
  709. ASSERT_EQ(&CRC, CG.lookupRefSCC(C2));
  710. ASSERT_EQ(&CRC, CG.lookupRefSCC(C3));
  711. ASSERT_EQ(&DRC, CG.lookupRefSCC(D2));
  712. ASSERT_EQ(&DRC, CG.lookupRefSCC(D3));
  713. ASSERT_EQ(1, std::distance(D2->begin(), D2->end()));
  714. // Add an edge to make the graph:
  715. //
  716. // d1 |
  717. // / \ |
  718. // d3--d2---. |
  719. // / \ | |
  720. // b1 c1 | |
  721. // / \ / \ / |
  722. // b3--b2 c3--c2 |
  723. // \ / |
  724. // a1 |
  725. // / \ |
  726. // a3--a2 |
  727. auto MergedRCs = CRC.insertIncomingRefEdge(D2, C2);
  728. // Make sure we connected the nodes.
  729. for (LazyCallGraph::Edge E : *D2) {
  730. if (&E.getNode() == &D3)
  731. continue;
  732. EXPECT_EQ(&C2, &E.getNode());
  733. }
  734. // And marked the D ref-SCC as no longer valid.
  735. EXPECT_EQ(1u, MergedRCs.size());
  736. EXPECT_EQ(&DRC, MergedRCs[0]);
  737. // Make sure we have the correct nodes in the SCC sets.
  738. EXPECT_EQ(&ARC, CG.lookupRefSCC(A1));
  739. EXPECT_EQ(&ARC, CG.lookupRefSCC(A2));
  740. EXPECT_EQ(&ARC, CG.lookupRefSCC(A3));
  741. EXPECT_EQ(&BRC, CG.lookupRefSCC(B1));
  742. EXPECT_EQ(&BRC, CG.lookupRefSCC(B2));
  743. EXPECT_EQ(&BRC, CG.lookupRefSCC(B3));
  744. EXPECT_EQ(&CRC, CG.lookupRefSCC(C1));
  745. EXPECT_EQ(&CRC, CG.lookupRefSCC(C2));
  746. EXPECT_EQ(&CRC, CG.lookupRefSCC(C3));
  747. EXPECT_EQ(&CRC, CG.lookupRefSCC(D1));
  748. EXPECT_EQ(&CRC, CG.lookupRefSCC(D2));
  749. EXPECT_EQ(&CRC, CG.lookupRefSCC(D3));
  750. // And that ancestry tests have been updated.
  751. EXPECT_TRUE(ARC.isParentOf(CRC));
  752. EXPECT_TRUE(BRC.isParentOf(CRC));
  753. // And verify the post-order walk reflects the updated structure.
  754. auto I = CG.postorder_ref_scc_begin(), E = CG.postorder_ref_scc_end();
  755. ASSERT_NE(I, E);
  756. EXPECT_EQ(&CRC, &*I) << "Actual RefSCC: " << *I;
  757. ASSERT_NE(++I, E);
  758. EXPECT_EQ(&BRC, &*I) << "Actual RefSCC: " << *I;
  759. ASSERT_NE(++I, E);
  760. EXPECT_EQ(&ARC, &*I) << "Actual RefSCC: " << *I;
  761. EXPECT_EQ(++I, E);
  762. }
  763. TEST(LazyCallGraphTest, IncomingEdgeInsertionRefGraph) {
  764. LLVMContext Context;
  765. // Another variation of the above test but with all the edges switched to
  766. // references rather than calls.
  767. std::unique_ptr<Module> M =
  768. parseAssembly(Context, DiamondOfTrianglesRefGraph);
  769. LazyCallGraph CG = buildCG(*M);
  770. // Force the graph to be fully expanded.
  771. CG.buildRefSCCs();
  772. for (LazyCallGraph::RefSCC &RC : CG.postorder_ref_sccs())
  773. dbgs() << "Formed RefSCC: " << RC << "\n";
  774. LazyCallGraph::Node &A1 = *CG.lookup(lookupFunction(*M, "a1"));
  775. LazyCallGraph::Node &A2 = *CG.lookup(lookupFunction(*M, "a2"));
  776. LazyCallGraph::Node &A3 = *CG.lookup(lookupFunction(*M, "a3"));
  777. LazyCallGraph::Node &B1 = *CG.lookup(lookupFunction(*M, "b1"));
  778. LazyCallGraph::Node &B2 = *CG.lookup(lookupFunction(*M, "b2"));
  779. LazyCallGraph::Node &B3 = *CG.lookup(lookupFunction(*M, "b3"));
  780. LazyCallGraph::Node &C1 = *CG.lookup(lookupFunction(*M, "c1"));
  781. LazyCallGraph::Node &C2 = *CG.lookup(lookupFunction(*M, "c2"));
  782. LazyCallGraph::Node &C3 = *CG.lookup(lookupFunction(*M, "c3"));
  783. LazyCallGraph::Node &D1 = *CG.lookup(lookupFunction(*M, "d1"));
  784. LazyCallGraph::Node &D2 = *CG.lookup(lookupFunction(*M, "d2"));
  785. LazyCallGraph::Node &D3 = *CG.lookup(lookupFunction(*M, "d3"));
  786. LazyCallGraph::RefSCC &ARC = *CG.lookupRefSCC(A1);
  787. LazyCallGraph::RefSCC &BRC = *CG.lookupRefSCC(B1);
  788. LazyCallGraph::RefSCC &CRC = *CG.lookupRefSCC(C1);
  789. LazyCallGraph::RefSCC &DRC = *CG.lookupRefSCC(D1);
  790. ASSERT_EQ(&ARC, CG.lookupRefSCC(A2));
  791. ASSERT_EQ(&ARC, CG.lookupRefSCC(A3));
  792. ASSERT_EQ(&BRC, CG.lookupRefSCC(B2));
  793. ASSERT_EQ(&BRC, CG.lookupRefSCC(B3));
  794. ASSERT_EQ(&CRC, CG.lookupRefSCC(C2));
  795. ASSERT_EQ(&CRC, CG.lookupRefSCC(C3));
  796. ASSERT_EQ(&DRC, CG.lookupRefSCC(D2));
  797. ASSERT_EQ(&DRC, CG.lookupRefSCC(D3));
  798. ASSERT_EQ(1, std::distance(D2->begin(), D2->end()));
  799. // Add an edge to make the graph:
  800. //
  801. // d1 |
  802. // / \ |
  803. // d3--d2---. |
  804. // / \ | |
  805. // b1 c1 | |
  806. // / \ / \ / |
  807. // b3--b2 c3--c2 |
  808. // \ / |
  809. // a1 |
  810. // / \ |
  811. // a3--a2 |
  812. auto MergedRCs = CRC.insertIncomingRefEdge(D2, C2);
  813. // Make sure we connected the nodes.
  814. for (LazyCallGraph::Edge E : *D2) {
  815. if (&E.getNode() == &D3)
  816. continue;
  817. EXPECT_EQ(&C2, &E.getNode());
  818. }
  819. // And marked the D ref-SCC as no longer valid.
  820. EXPECT_EQ(1u, MergedRCs.size());
  821. EXPECT_EQ(&DRC, MergedRCs[0]);
  822. // Make sure we have the correct nodes in the SCC sets.
  823. EXPECT_EQ(&ARC, CG.lookupRefSCC(A1));
  824. EXPECT_EQ(&ARC, CG.lookupRefSCC(A2));
  825. EXPECT_EQ(&ARC, CG.lookupRefSCC(A3));
  826. EXPECT_EQ(&BRC, CG.lookupRefSCC(B1));
  827. EXPECT_EQ(&BRC, CG.lookupRefSCC(B2));
  828. EXPECT_EQ(&BRC, CG.lookupRefSCC(B3));
  829. EXPECT_EQ(&CRC, CG.lookupRefSCC(C1));
  830. EXPECT_EQ(&CRC, CG.lookupRefSCC(C2));
  831. EXPECT_EQ(&CRC, CG.lookupRefSCC(C3));
  832. EXPECT_EQ(&CRC, CG.lookupRefSCC(D1));
  833. EXPECT_EQ(&CRC, CG.lookupRefSCC(D2));
  834. EXPECT_EQ(&CRC, CG.lookupRefSCC(D3));
  835. // And that ancestry tests have been updated.
  836. EXPECT_TRUE(ARC.isParentOf(CRC));
  837. EXPECT_TRUE(BRC.isParentOf(CRC));
  838. // And verify the post-order walk reflects the updated structure.
  839. auto I = CG.postorder_ref_scc_begin(), E = CG.postorder_ref_scc_end();
  840. ASSERT_NE(I, E);
  841. EXPECT_EQ(&CRC, &*I) << "Actual RefSCC: " << *I;
  842. ASSERT_NE(++I, E);
  843. EXPECT_EQ(&BRC, &*I) << "Actual RefSCC: " << *I;
  844. ASSERT_NE(++I, E);
  845. EXPECT_EQ(&ARC, &*I) << "Actual RefSCC: " << *I;
  846. EXPECT_EQ(++I, E);
  847. }
  848. TEST(LazyCallGraphTest, IncomingEdgeInsertionLargeCallCycle) {
  849. LLVMContext Context;
  850. std::unique_ptr<Module> M = parseAssembly(Context, "define void @a() {\n"
  851. "entry:\n"
  852. " call void @b()\n"
  853. " ret void\n"
  854. "}\n"
  855. "define void @b() {\n"
  856. "entry:\n"
  857. " call void @c()\n"
  858. " ret void\n"
  859. "}\n"
  860. "define void @c() {\n"
  861. "entry:\n"
  862. " call void @d()\n"
  863. " ret void\n"
  864. "}\n"
  865. "define void @d() {\n"
  866. "entry:\n"
  867. " ret void\n"
  868. "}\n");
  869. LazyCallGraph CG = buildCG(*M);
  870. // Force the graph to be fully expanded.
  871. CG.buildRefSCCs();
  872. for (LazyCallGraph::RefSCC &RC : CG.postorder_ref_sccs())
  873. dbgs() << "Formed RefSCC: " << RC << "\n";
  874. LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
  875. LazyCallGraph::Node &B = *CG.lookup(lookupFunction(*M, "b"));
  876. LazyCallGraph::Node &C = *CG.lookup(lookupFunction(*M, "c"));
  877. LazyCallGraph::Node &D = *CG.lookup(lookupFunction(*M, "d"));
  878. LazyCallGraph::SCC &AC = *CG.lookupSCC(A);
  879. LazyCallGraph::SCC &BC = *CG.lookupSCC(B);
  880. LazyCallGraph::SCC &CC = *CG.lookupSCC(C);
  881. LazyCallGraph::SCC &DC = *CG.lookupSCC(D);
  882. LazyCallGraph::RefSCC &ARC = *CG.lookupRefSCC(A);
  883. LazyCallGraph::RefSCC &BRC = *CG.lookupRefSCC(B);
  884. LazyCallGraph::RefSCC &CRC = *CG.lookupRefSCC(C);
  885. LazyCallGraph::RefSCC &DRC = *CG.lookupRefSCC(D);
  886. // Connect the top to the bottom forming a large RefSCC made up mostly of calls.
  887. auto MergedRCs = ARC.insertIncomingRefEdge(D, A);
  888. // Make sure we connected the nodes.
  889. EXPECT_NE(D->begin(), D->end());
  890. EXPECT_EQ(&A, &D->begin()->getNode());
  891. // Check that we have the dead RCs, but ignore the order.
  892. EXPECT_EQ(3u, MergedRCs.size());
  893. EXPECT_NE(find(MergedRCs, &BRC), MergedRCs.end());
  894. EXPECT_NE(find(MergedRCs, &CRC), MergedRCs.end());
  895. EXPECT_NE(find(MergedRCs, &DRC), MergedRCs.end());
  896. // Make sure the nodes point to the right place now.
  897. EXPECT_EQ(&ARC, CG.lookupRefSCC(A));
  898. EXPECT_EQ(&ARC, CG.lookupRefSCC(B));
  899. EXPECT_EQ(&ARC, CG.lookupRefSCC(C));
  900. EXPECT_EQ(&ARC, CG.lookupRefSCC(D));
  901. // Check that the SCCs are in postorder.
  902. EXPECT_EQ(4, ARC.size());
  903. EXPECT_EQ(&DC, &ARC[0]);
  904. EXPECT_EQ(&CC, &ARC[1]);
  905. EXPECT_EQ(&BC, &ARC[2]);
  906. EXPECT_EQ(&AC, &ARC[3]);
  907. // And verify the post-order walk reflects the updated structure.
  908. auto I = CG.postorder_ref_scc_begin(), E = CG.postorder_ref_scc_end();
  909. ASSERT_NE(I, E);
  910. EXPECT_EQ(&ARC, &*I) << "Actual RefSCC: " << *I;
  911. EXPECT_EQ(++I, E);
  912. }
  913. TEST(LazyCallGraphTest, IncomingEdgeInsertionLargeRefCycle) {
  914. LLVMContext Context;
  915. std::unique_ptr<Module> M =
  916. parseAssembly(Context, "define void @a() {\n"
  917. "entry:\n"
  918. " %p = alloca void ()*\n"
  919. " store void ()* @b, void ()** %p\n"
  920. " ret void\n"
  921. "}\n"
  922. "define void @b() {\n"
  923. "entry:\n"
  924. " %p = alloca void ()*\n"
  925. " store void ()* @c, void ()** %p\n"
  926. " ret void\n"
  927. "}\n"
  928. "define void @c() {\n"
  929. "entry:\n"
  930. " %p = alloca void ()*\n"
  931. " store void ()* @d, void ()** %p\n"
  932. " ret void\n"
  933. "}\n"
  934. "define void @d() {\n"
  935. "entry:\n"
  936. " ret void\n"
  937. "}\n");
  938. LazyCallGraph CG = buildCG(*M);
  939. // Force the graph to be fully expanded.
  940. CG.buildRefSCCs();
  941. for (LazyCallGraph::RefSCC &RC : CG.postorder_ref_sccs())
  942. dbgs() << "Formed RefSCC: " << RC << "\n";
  943. LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
  944. LazyCallGraph::Node &B = *CG.lookup(lookupFunction(*M, "b"));
  945. LazyCallGraph::Node &C = *CG.lookup(lookupFunction(*M, "c"));
  946. LazyCallGraph::Node &D = *CG.lookup(lookupFunction(*M, "d"));
  947. LazyCallGraph::RefSCC &ARC = *CG.lookupRefSCC(A);
  948. LazyCallGraph::RefSCC &BRC = *CG.lookupRefSCC(B);
  949. LazyCallGraph::RefSCC &CRC = *CG.lookupRefSCC(C);
  950. LazyCallGraph::RefSCC &DRC = *CG.lookupRefSCC(D);
  951. // Connect the top to the bottom forming a large RefSCC made up just of
  952. // references.
  953. auto MergedRCs = ARC.insertIncomingRefEdge(D, A);
  954. // Make sure we connected the nodes.
  955. EXPECT_NE(D->begin(), D->end());
  956. EXPECT_EQ(&A, &D->begin()->getNode());
  957. // Check that we have the dead RCs, but ignore the order.
  958. EXPECT_EQ(3u, MergedRCs.size());
  959. EXPECT_NE(find(MergedRCs, &BRC), MergedRCs.end());
  960. EXPECT_NE(find(MergedRCs, &CRC), MergedRCs.end());
  961. EXPECT_NE(find(MergedRCs, &DRC), MergedRCs.end());
  962. // Make sure the nodes point to the right place now.
  963. EXPECT_EQ(&ARC, CG.lookupRefSCC(A));
  964. EXPECT_EQ(&ARC, CG.lookupRefSCC(B));
  965. EXPECT_EQ(&ARC, CG.lookupRefSCC(C));
  966. EXPECT_EQ(&ARC, CG.lookupRefSCC(D));
  967. // And verify the post-order walk reflects the updated structure.
  968. auto I = CG.postorder_ref_scc_begin(), End = CG.postorder_ref_scc_end();
  969. ASSERT_NE(I, End);
  970. EXPECT_EQ(&ARC, &*I) << "Actual RefSCC: " << *I;
  971. EXPECT_EQ(++I, End);
  972. }
  973. TEST(LazyCallGraphTest, InlineAndDeleteFunction) {
  974. LLVMContext Context;
  975. // We want to ensure we can delete nodes from relatively complex graphs and
  976. // so use the diamond of triangles graph defined above.
  977. //
  978. // The ascii diagram is repeated here for easy reference.
  979. //
  980. // d1 |
  981. // / \ |
  982. // d3--d2 |
  983. // / \ |
  984. // b1 c1 |
  985. // / \ / \ |
  986. // b3--b2 c3--c2 |
  987. // \ / |
  988. // a1 |
  989. // / \ |
  990. // a3--a2 |
  991. //
  992. std::unique_ptr<Module> M = parseAssembly(Context, DiamondOfTriangles);
  993. LazyCallGraph CG = buildCG(*M);
  994. // Force the graph to be fully expanded.
  995. CG.buildRefSCCs();
  996. for (LazyCallGraph::RefSCC &RC : CG.postorder_ref_sccs())
  997. dbgs() << "Formed RefSCC: " << RC << "\n";
  998. LazyCallGraph::Node &A1 = *CG.lookup(lookupFunction(*M, "a1"));
  999. LazyCallGraph::Node &A2 = *CG.lookup(lookupFunction(*M, "a2"));
  1000. LazyCallGraph::Node &A3 = *CG.lookup(lookupFunction(*M, "a3"));
  1001. LazyCallGraph::Node &B1 = *CG.lookup(lookupFunction(*M, "b1"));
  1002. LazyCallGraph::Node &B2 = *CG.lookup(lookupFunction(*M, "b2"));
  1003. LazyCallGraph::Node &B3 = *CG.lookup(lookupFunction(*M, "b3"));
  1004. LazyCallGraph::Node &C1 = *CG.lookup(lookupFunction(*M, "c1"));
  1005. LazyCallGraph::Node &C2 = *CG.lookup(lookupFunction(*M, "c2"));
  1006. LazyCallGraph::Node &C3 = *CG.lookup(lookupFunction(*M, "c3"));
  1007. LazyCallGraph::Node &D1 = *CG.lookup(lookupFunction(*M, "d1"));
  1008. LazyCallGraph::Node &D2 = *CG.lookup(lookupFunction(*M, "d2"));
  1009. LazyCallGraph::Node &D3 = *CG.lookup(lookupFunction(*M, "d3"));
  1010. LazyCallGraph::RefSCC &ARC = *CG.lookupRefSCC(A1);
  1011. LazyCallGraph::RefSCC &BRC = *CG.lookupRefSCC(B1);
  1012. LazyCallGraph::RefSCC &CRC = *CG.lookupRefSCC(C1);
  1013. LazyCallGraph::RefSCC &DRC = *CG.lookupRefSCC(D1);
  1014. ASSERT_EQ(&ARC, CG.lookupRefSCC(A2));
  1015. ASSERT_EQ(&ARC, CG.lookupRefSCC(A3));
  1016. ASSERT_EQ(&BRC, CG.lookupRefSCC(B2));
  1017. ASSERT_EQ(&BRC, CG.lookupRefSCC(B3));
  1018. ASSERT_EQ(&CRC, CG.lookupRefSCC(C2));
  1019. ASSERT_EQ(&CRC, CG.lookupRefSCC(C3));
  1020. ASSERT_EQ(&DRC, CG.lookupRefSCC(D2));
  1021. ASSERT_EQ(&DRC, CG.lookupRefSCC(D3));
  1022. ASSERT_EQ(1, std::distance(D2->begin(), D2->end()));
  1023. // Delete d2 from the graph, as if it had been inlined.
  1024. //
  1025. // d1 |
  1026. // / / |
  1027. // d3--. |
  1028. // / \ |
  1029. // b1 c1 |
  1030. // / \ / \ |
  1031. // b3--b2 c3--c2 |
  1032. // \ / |
  1033. // a1 |
  1034. // / \ |
  1035. // a3--a2 |
  1036. Function &D2F = D2.getFunction();
  1037. CallInst *C1Call = nullptr, *D1Call = nullptr;
  1038. for (User *U : D2F.users()) {
  1039. CallInst *CI = dyn_cast<CallInst>(U);
  1040. ASSERT_TRUE(CI) << "Expected a call: " << *U;
  1041. if (CI->getParent()->getParent() == &C1.getFunction()) {
  1042. ASSERT_EQ(nullptr, C1Call) << "Found too many C1 calls: " << *CI;
  1043. C1Call = CI;
  1044. } else if (CI->getParent()->getParent() == &D1.getFunction()) {
  1045. ASSERT_EQ(nullptr, D1Call) << "Found too many D1 calls: " << *CI;
  1046. D1Call = CI;
  1047. } else {
  1048. FAIL() << "Found an unexpected call instruction: " << *CI;
  1049. }
  1050. }
  1051. ASSERT_NE(C1Call, nullptr);
  1052. ASSERT_NE(D1Call, nullptr);
  1053. ASSERT_EQ(&D2F, C1Call->getCalledFunction());
  1054. ASSERT_EQ(&D2F, D1Call->getCalledFunction());
  1055. C1Call->setCalledFunction(&D3.getFunction());
  1056. D1Call->setCalledFunction(&D3.getFunction());
  1057. ASSERT_EQ(0u, D2F.getNumUses());
  1058. // Insert new edges first.
  1059. CRC.insertTrivialCallEdge(C1, D3);
  1060. DRC.insertTrivialCallEdge(D1, D3);
  1061. // Then remove the old ones.
  1062. LazyCallGraph::SCC &DC = *CG.lookupSCC(D2);
  1063. auto NewCs = DRC.switchInternalEdgeToRef(D1, D2);
  1064. EXPECT_EQ(&DC, CG.lookupSCC(D2));
  1065. EXPECT_EQ(NewCs.end(), std::next(NewCs.begin()));
  1066. LazyCallGraph::SCC &NewDC = *NewCs.begin();
  1067. EXPECT_EQ(&NewDC, CG.lookupSCC(D1));
  1068. EXPECT_EQ(&NewDC, CG.lookupSCC(D3));
  1069. auto NewRCs = DRC.removeInternalRefEdge(D1, D2);
  1070. EXPECT_EQ(&DRC, CG.lookupRefSCC(D2));
  1071. EXPECT_EQ(NewRCs.end(), std::next(NewRCs.begin()));
  1072. LazyCallGraph::RefSCC &NewDRC = **NewRCs.begin();
  1073. EXPECT_EQ(&NewDRC, CG.lookupRefSCC(D1));
  1074. EXPECT_EQ(&NewDRC, CG.lookupRefSCC(D3));
  1075. EXPECT_FALSE(NewDRC.isParentOf(DRC));
  1076. EXPECT_TRUE(CRC.isParentOf(DRC));
  1077. EXPECT_TRUE(CRC.isParentOf(NewDRC));
  1078. EXPECT_TRUE(DRC.isParentOf(NewDRC));
  1079. CRC.removeOutgoingEdge(C1, D2);
  1080. EXPECT_FALSE(CRC.isParentOf(DRC));
  1081. EXPECT_TRUE(CRC.isParentOf(NewDRC));
  1082. EXPECT_TRUE(DRC.isParentOf(NewDRC));
  1083. // Now that we've updated the call graph, D2 is dead, so remove it.
  1084. CG.removeDeadFunction(D2F);
  1085. // Check that the graph still looks the same.
  1086. EXPECT_EQ(&ARC, CG.lookupRefSCC(A1));
  1087. EXPECT_EQ(&ARC, CG.lookupRefSCC(A2));
  1088. EXPECT_EQ(&ARC, CG.lookupRefSCC(A3));
  1089. EXPECT_EQ(&BRC, CG.lookupRefSCC(B1));
  1090. EXPECT_EQ(&BRC, CG.lookupRefSCC(B2));
  1091. EXPECT_EQ(&BRC, CG.lookupRefSCC(B3));
  1092. EXPECT_EQ(&CRC, CG.lookupRefSCC(C1));
  1093. EXPECT_EQ(&CRC, CG.lookupRefSCC(C2));
  1094. EXPECT_EQ(&CRC, CG.lookupRefSCC(C3));
  1095. EXPECT_EQ(&NewDRC, CG.lookupRefSCC(D1));
  1096. EXPECT_EQ(&NewDRC, CG.lookupRefSCC(D3));
  1097. EXPECT_TRUE(CRC.isParentOf(NewDRC));
  1098. // Verify the post-order walk hasn't changed.
  1099. auto I = CG.postorder_ref_scc_begin(), E = CG.postorder_ref_scc_end();
  1100. ASSERT_NE(I, E);
  1101. EXPECT_EQ(&NewDRC, &*I) << "Actual RefSCC: " << *I;
  1102. ASSERT_NE(++I, E);
  1103. EXPECT_EQ(&CRC, &*I) << "Actual RefSCC: " << *I;
  1104. ASSERT_NE(++I, E);
  1105. EXPECT_EQ(&BRC, &*I) << "Actual RefSCC: " << *I;
  1106. ASSERT_NE(++I, E);
  1107. EXPECT_EQ(&ARC, &*I) << "Actual RefSCC: " << *I;
  1108. EXPECT_EQ(++I, E);
  1109. }
  1110. TEST(LazyCallGraphTest, InternalEdgeMutation) {
  1111. LLVMContext Context;
  1112. std::unique_ptr<Module> M = parseAssembly(Context, "define void @a() {\n"
  1113. "entry:\n"
  1114. " call void @b()\n"
  1115. " ret void\n"
  1116. "}\n"
  1117. "define void @b() {\n"
  1118. "entry:\n"
  1119. " call void @c()\n"
  1120. " ret void\n"
  1121. "}\n"
  1122. "define void @c() {\n"
  1123. "entry:\n"
  1124. " call void @a()\n"
  1125. " ret void\n"
  1126. "}\n");
  1127. LazyCallGraph CG = buildCG(*M);
  1128. // Force the graph to be fully expanded.
  1129. CG.buildRefSCCs();
  1130. auto I = CG.postorder_ref_scc_begin();
  1131. LazyCallGraph::RefSCC &RC = *I++;
  1132. EXPECT_EQ(CG.postorder_ref_scc_end(), I);
  1133. LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
  1134. LazyCallGraph::Node &B = *CG.lookup(lookupFunction(*M, "b"));
  1135. LazyCallGraph::Node &C = *CG.lookup(lookupFunction(*M, "c"));
  1136. EXPECT_EQ(&RC, CG.lookupRefSCC(A));
  1137. EXPECT_EQ(&RC, CG.lookupRefSCC(B));
  1138. EXPECT_EQ(&RC, CG.lookupRefSCC(C));
  1139. EXPECT_EQ(1, RC.size());
  1140. EXPECT_EQ(&*RC.begin(), CG.lookupSCC(A));
  1141. EXPECT_EQ(&*RC.begin(), CG.lookupSCC(B));
  1142. EXPECT_EQ(&*RC.begin(), CG.lookupSCC(C));
  1143. // Insert an edge from 'a' to 'c'. Nothing changes about the graph.
  1144. RC.insertInternalRefEdge(A, C);
  1145. EXPECT_EQ(2, std::distance(A->begin(), A->end()));
  1146. EXPECT_EQ(&RC, CG.lookupRefSCC(A));
  1147. EXPECT_EQ(&RC, CG.lookupRefSCC(B));
  1148. EXPECT_EQ(&RC, CG.lookupRefSCC(C));
  1149. EXPECT_EQ(1, RC.size());
  1150. EXPECT_EQ(&*RC.begin(), CG.lookupSCC(A));
  1151. EXPECT_EQ(&*RC.begin(), CG.lookupSCC(B));
  1152. EXPECT_EQ(&*RC.begin(), CG.lookupSCC(C));
  1153. // Switch the call edge from 'b' to 'c' to a ref edge. This will break the
  1154. // call cycle and cause us to form more SCCs. The RefSCC will remain the same
  1155. // though.
  1156. auto NewCs = RC.switchInternalEdgeToRef(B, C);
  1157. EXPECT_EQ(&RC, CG.lookupRefSCC(A));
  1158. EXPECT_EQ(&RC, CG.lookupRefSCC(B));
  1159. EXPECT_EQ(&RC, CG.lookupRefSCC(C));
  1160. auto J = RC.begin();
  1161. // The SCCs must be in *post-order* which means successors before
  1162. // predecessors. At this point we have call edges from C to A and from A to
  1163. // B. The only valid postorder is B, A, C.
  1164. EXPECT_EQ(&*J++, CG.lookupSCC(B));
  1165. EXPECT_EQ(&*J++, CG.lookupSCC(A));
  1166. EXPECT_EQ(&*J++, CG.lookupSCC(C));
  1167. EXPECT_EQ(RC.end(), J);
  1168. // And the returned range must be the slice of this sequence containing new
  1169. // SCCs.
  1170. EXPECT_EQ(RC.begin(), NewCs.begin());
  1171. EXPECT_EQ(std::prev(RC.end()), NewCs.end());
  1172. // Test turning the ref edge from A to C into a call edge. This will form an
  1173. // SCC out of A and C. Since we previously had a call edge from C to A, the
  1174. // C SCC should be preserved and have A merged into it while the A SCC should
  1175. // be invalidated.
  1176. LazyCallGraph::SCC &AC = *CG.lookupSCC(A);
  1177. LazyCallGraph::SCC &CC = *CG.lookupSCC(C);
  1178. EXPECT_TRUE(RC.switchInternalEdgeToCall(A, C, [&](ArrayRef<LazyCallGraph::SCC *> MergedCs) {
  1179. ASSERT_EQ(1u, MergedCs.size());
  1180. EXPECT_EQ(&AC, MergedCs[0]);
  1181. }));
  1182. EXPECT_EQ(2, CC.size());
  1183. EXPECT_EQ(&CC, CG.lookupSCC(A));
  1184. EXPECT_EQ(&CC, CG.lookupSCC(C));
  1185. J = RC.begin();
  1186. EXPECT_EQ(&*J++, CG.lookupSCC(B));
  1187. EXPECT_EQ(&*J++, CG.lookupSCC(C));
  1188. EXPECT_EQ(RC.end(), J);
  1189. }
  1190. TEST(LazyCallGraphTest, InternalEdgeRemoval) {
  1191. LLVMContext Context;
  1192. // A nice fully connected (including self-edges) RefSCC.
  1193. std::unique_ptr<Module> M = parseAssembly(
  1194. Context, "define void @a(i8** %ptr) {\n"
  1195. "entry:\n"
  1196. " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
  1197. " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
  1198. " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
  1199. " ret void\n"
  1200. "}\n"
  1201. "define void @b(i8** %ptr) {\n"
  1202. "entry:\n"
  1203. " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
  1204. " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
  1205. " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
  1206. " ret void\n"
  1207. "}\n"
  1208. "define void @c(i8** %ptr) {\n"
  1209. "entry:\n"
  1210. " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
  1211. " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
  1212. " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
  1213. " ret void\n"
  1214. "}\n");
  1215. LazyCallGraph CG = buildCG(*M);
  1216. // Force the graph to be fully expanded.
  1217. CG.buildRefSCCs();
  1218. auto I = CG.postorder_ref_scc_begin(), E = CG.postorder_ref_scc_end();
  1219. LazyCallGraph::RefSCC &RC = *I;
  1220. EXPECT_EQ(E, std::next(I));
  1221. LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
  1222. LazyCallGraph::Node &B = *CG.lookup(lookupFunction(*M, "b"));
  1223. LazyCallGraph::Node &C = *CG.lookup(lookupFunction(*M, "c"));
  1224. EXPECT_EQ(&RC, CG.lookupRefSCC(A));
  1225. EXPECT_EQ(&RC, CG.lookupRefSCC(B));
  1226. EXPECT_EQ(&RC, CG.lookupRefSCC(C));
  1227. // Remove the edge from b -> a, which should leave the 3 functions still in
  1228. // a single connected component because of a -> b -> c -> a.
  1229. SmallVector<LazyCallGraph::RefSCC *, 1> NewRCs =
  1230. RC.removeInternalRefEdge(B, A);
  1231. EXPECT_EQ(0u, NewRCs.size());
  1232. EXPECT_EQ(&RC, CG.lookupRefSCC(A));
  1233. EXPECT_EQ(&RC, CG.lookupRefSCC(B));
  1234. EXPECT_EQ(&RC, CG.lookupRefSCC(C));
  1235. auto J = CG.postorder_ref_scc_begin();
  1236. EXPECT_EQ(I, J);
  1237. EXPECT_EQ(&RC, &*J);
  1238. EXPECT_EQ(E, std::next(J));
  1239. // Remove the edge from c -> a, which should leave 'a' in the original RefSCC
  1240. // and form a new RefSCC for 'b' and 'c'.
  1241. NewRCs = RC.removeInternalRefEdge(C, A);
  1242. EXPECT_EQ(1u, NewRCs.size());
  1243. EXPECT_EQ(&RC, CG.lookupRefSCC(A));
  1244. EXPECT_EQ(1, std::distance(RC.begin(), RC.end()));
  1245. LazyCallGraph::RefSCC &RC2 = *CG.lookupRefSCC(B);
  1246. EXPECT_EQ(&RC2, CG.lookupRefSCC(C));
  1247. EXPECT_EQ(&RC2, NewRCs[0]);
  1248. J = CG.postorder_ref_scc_begin();
  1249. EXPECT_NE(I, J);
  1250. EXPECT_EQ(&RC2, &*J);
  1251. ++J;
  1252. EXPECT_EQ(I, J);
  1253. EXPECT_EQ(&RC, &*J);
  1254. ++I;
  1255. EXPECT_EQ(E, I);
  1256. ++J;
  1257. EXPECT_EQ(E, J);
  1258. }
  1259. TEST(LazyCallGraphTest, InternalNoOpEdgeRemoval) {
  1260. LLVMContext Context;
  1261. // A graph with a single cycle formed both from call and reference edges
  1262. // which makes the reference edges trivial to delete. The graph looks like:
  1263. //
  1264. // Reference edges: a -> b -> c -> a
  1265. // Call edges: a -> c -> b -> a
  1266. std::unique_ptr<Module> M = parseAssembly(
  1267. Context, "define void @a(i8** %ptr) {\n"
  1268. "entry:\n"
  1269. " call void @b(i8** %ptr)\n"
  1270. " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
  1271. " ret void\n"
  1272. "}\n"
  1273. "define void @b(i8** %ptr) {\n"
  1274. "entry:\n"
  1275. " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
  1276. " call void @c(i8** %ptr)\n"
  1277. " ret void\n"
  1278. "}\n"
  1279. "define void @c(i8** %ptr) {\n"
  1280. "entry:\n"
  1281. " call void @a(i8** %ptr)\n"
  1282. " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
  1283. " ret void\n"
  1284. "}\n");
  1285. LazyCallGraph CG = buildCG(*M);
  1286. // Force the graph to be fully expanded.
  1287. CG.buildRefSCCs();
  1288. auto I = CG.postorder_ref_scc_begin(), E = CG.postorder_ref_scc_end();
  1289. LazyCallGraph::RefSCC &RC = *I;
  1290. EXPECT_EQ(E, std::next(I));
  1291. LazyCallGraph::SCC &C = *RC.begin();
  1292. EXPECT_EQ(RC.end(), std::next(RC.begin()));
  1293. LazyCallGraph::Node &AN = *CG.lookup(lookupFunction(*M, "a"));
  1294. LazyCallGraph::Node &BN = *CG.lookup(lookupFunction(*M, "b"));
  1295. LazyCallGraph::Node &CN = *CG.lookup(lookupFunction(*M, "c"));
  1296. EXPECT_EQ(&RC, CG.lookupRefSCC(AN));
  1297. EXPECT_EQ(&RC, CG.lookupRefSCC(BN));
  1298. EXPECT_EQ(&RC, CG.lookupRefSCC(CN));
  1299. EXPECT_EQ(&C, CG.lookupSCC(AN));
  1300. EXPECT_EQ(&C, CG.lookupSCC(BN));
  1301. EXPECT_EQ(&C, CG.lookupSCC(CN));
  1302. // Remove the edge from a -> c which doesn't change anything.
  1303. SmallVector<LazyCallGraph::RefSCC *, 1> NewRCs =
  1304. RC.removeInternalRefEdge(AN, CN);
  1305. EXPECT_EQ(0u, NewRCs.size());
  1306. EXPECT_EQ(&RC, CG.lookupRefSCC(AN));
  1307. EXPECT_EQ(&RC, CG.lookupRefSCC(BN));
  1308. EXPECT_EQ(&RC, CG.lookupRefSCC(CN));
  1309. EXPECT_EQ(&C, CG.lookupSCC(AN));
  1310. EXPECT_EQ(&C, CG.lookupSCC(BN));
  1311. EXPECT_EQ(&C, CG.lookupSCC(CN));
  1312. auto J = CG.postorder_ref_scc_begin();
  1313. EXPECT_EQ(I, J);
  1314. EXPECT_EQ(&RC, &*J);
  1315. EXPECT_EQ(E, std::next(J));
  1316. // Remove the edge from b -> a and c -> b; again this doesn't change
  1317. // anything.
  1318. NewRCs = RC.removeInternalRefEdge(BN, AN);
  1319. NewRCs = RC.removeInternalRefEdge(CN, BN);
  1320. EXPECT_EQ(0u, NewRCs.size());
  1321. EXPECT_EQ(&RC, CG.lookupRefSCC(AN));
  1322. EXPECT_EQ(&RC, CG.lookupRefSCC(BN));
  1323. EXPECT_EQ(&RC, CG.lookupRefSCC(CN));
  1324. EXPECT_EQ(&C, CG.lookupSCC(AN));
  1325. EXPECT_EQ(&C, CG.lookupSCC(BN));
  1326. EXPECT_EQ(&C, CG.lookupSCC(CN));
  1327. J = CG.postorder_ref_scc_begin();
  1328. EXPECT_EQ(I, J);
  1329. EXPECT_EQ(&RC, &*J);
  1330. EXPECT_EQ(E, std::next(J));
  1331. }
  1332. TEST(LazyCallGraphTest, InternalCallEdgeToRef) {
  1333. LLVMContext Context;
  1334. // A nice fully connected (including self-edges) SCC (and RefSCC)
  1335. std::unique_ptr<Module> M = parseAssembly(Context, "define void @a() {\n"
  1336. "entry:\n"
  1337. " call void @a()\n"
  1338. " call void @b()\n"
  1339. " call void @c()\n"
  1340. " ret void\n"
  1341. "}\n"
  1342. "define void @b() {\n"
  1343. "entry:\n"
  1344. " call void @a()\n"
  1345. " call void @b()\n"
  1346. " call void @c()\n"
  1347. " ret void\n"
  1348. "}\n"
  1349. "define void @c() {\n"
  1350. "entry:\n"
  1351. " call void @a()\n"
  1352. " call void @b()\n"
  1353. " call void @c()\n"
  1354. " ret void\n"
  1355. "}\n");
  1356. LazyCallGraph CG = buildCG(*M);
  1357. // Force the graph to be fully expanded.
  1358. CG.buildRefSCCs();
  1359. auto I = CG.postorder_ref_scc_begin();
  1360. LazyCallGraph::RefSCC &RC = *I++;
  1361. EXPECT_EQ(CG.postorder_ref_scc_end(), I);
  1362. EXPECT_EQ(1, RC.size());
  1363. LazyCallGraph::SCC &AC = *RC.begin();
  1364. LazyCallGraph::Node &AN = *CG.lookup(lookupFunction(*M, "a"));
  1365. LazyCallGraph::Node &BN = *CG.lookup(lookupFunction(*M, "b"));
  1366. LazyCallGraph::Node &CN = *CG.lookup(lookupFunction(*M, "c"));
  1367. EXPECT_EQ(&AC, CG.lookupSCC(AN));
  1368. EXPECT_EQ(&AC, CG.lookupSCC(BN));
  1369. EXPECT_EQ(&AC, CG.lookupSCC(CN));
  1370. // Remove the call edge from b -> a to a ref edge, which should leave the
  1371. // 3 functions still in a single connected component because of a -> b ->
  1372. // c -> a.
  1373. auto NewCs = RC.switchInternalEdgeToRef(BN, AN);
  1374. EXPECT_EQ(NewCs.begin(), NewCs.end());
  1375. EXPECT_EQ(1, RC.size());
  1376. EXPECT_EQ(&AC, CG.lookupSCC(AN));
  1377. EXPECT_EQ(&AC, CG.lookupSCC(BN));
  1378. EXPECT_EQ(&AC, CG.lookupSCC(CN));
  1379. // Remove the edge from c -> a, which should leave 'a' in the original SCC
  1380. // and form a new SCC for 'b' and 'c'.
  1381. NewCs = RC.switchInternalEdgeToRef(CN, AN);
  1382. EXPECT_EQ(1, std::distance(NewCs.begin(), NewCs.end()));
  1383. EXPECT_EQ(2, RC.size());
  1384. EXPECT_EQ(&AC, CG.lookupSCC(AN));
  1385. LazyCallGraph::SCC &BC = *CG.lookupSCC(BN);
  1386. EXPECT_NE(&BC, &AC);
  1387. EXPECT_EQ(&BC, CG.lookupSCC(CN));
  1388. auto J = RC.find(AC);
  1389. EXPECT_EQ(&AC, &*J);
  1390. --J;
  1391. EXPECT_EQ(&BC, &*J);
  1392. EXPECT_EQ(RC.begin(), J);
  1393. EXPECT_EQ(J, NewCs.begin());
  1394. // Remove the edge from c -> b, which should leave 'b' in the original SCC
  1395. // and form a new SCC for 'c'. It shouldn't change 'a's SCC.
  1396. NewCs = RC.switchInternalEdgeToRef(CN, BN);
  1397. EXPECT_EQ(1, std::distance(NewCs.begin(), NewCs.end()));
  1398. EXPECT_EQ(3, RC.size());
  1399. EXPECT_EQ(&AC, CG.lookupSCC(AN));
  1400. EXPECT_EQ(&BC, CG.lookupSCC(BN));
  1401. LazyCallGraph::SCC &CC = *CG.lookupSCC(CN);
  1402. EXPECT_NE(&CC, &AC);
  1403. EXPECT_NE(&CC, &BC);
  1404. J = RC.find(AC);
  1405. EXPECT_EQ(&AC, &*J);
  1406. --J;
  1407. EXPECT_EQ(&BC, &*J);
  1408. --J;
  1409. EXPECT_EQ(&CC, &*J);
  1410. EXPECT_EQ(RC.begin(), J);
  1411. EXPECT_EQ(J, NewCs.begin());
  1412. }
  1413. TEST(LazyCallGraphTest, InternalRefEdgeToCall) {
  1414. LLVMContext Context;
  1415. // Basic tests for making a ref edge a call. This hits the basics of the
  1416. // process only.
  1417. std::unique_ptr<Module> M =
  1418. parseAssembly(Context, "define void @a() {\n"
  1419. "entry:\n"
  1420. " call void @b()\n"
  1421. " call void @c()\n"
  1422. " store void()* @d, void()** undef\n"
  1423. " ret void\n"
  1424. "}\n"
  1425. "define void @b() {\n"
  1426. "entry:\n"
  1427. " store void()* @c, void()** undef\n"
  1428. " call void @d()\n"
  1429. " ret void\n"
  1430. "}\n"
  1431. "define void @c() {\n"
  1432. "entry:\n"
  1433. " store void()* @b, void()** undef\n"
  1434. " call void @d()\n"
  1435. " ret void\n"
  1436. "}\n"
  1437. "define void @d() {\n"
  1438. "entry:\n"
  1439. " store void()* @a, void()** undef\n"
  1440. " ret void\n"
  1441. "}\n");
  1442. LazyCallGraph CG = buildCG(*M);
  1443. // Force the graph to be fully expanded.
  1444. CG.buildRefSCCs();
  1445. auto I = CG.postorder_ref_scc_begin();
  1446. LazyCallGraph::RefSCC &RC = *I++;
  1447. EXPECT_EQ(CG.postorder_ref_scc_end(), I);
  1448. LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
  1449. LazyCallGraph::Node &B = *CG.lookup(lookupFunction(*M, "b"));
  1450. LazyCallGraph::Node &C = *CG.lookup(lookupFunction(*M, "c"));
  1451. LazyCallGraph::Node &D = *CG.lookup(lookupFunction(*M, "d"));
  1452. LazyCallGraph::SCC &AC = *CG.lookupSCC(A);
  1453. LazyCallGraph::SCC &BC = *CG.lookupSCC(B);
  1454. LazyCallGraph::SCC &CC = *CG.lookupSCC(C);
  1455. LazyCallGraph::SCC &DC = *CG.lookupSCC(D);
  1456. // Check the initial post-order. Note that B and C could be flipped here (and
  1457. // in our mutation) without changing the nature of this test.
  1458. ASSERT_EQ(4, RC.size());
  1459. EXPECT_EQ(&DC, &RC[0]);
  1460. EXPECT_EQ(&BC, &RC[1]);
  1461. EXPECT_EQ(&CC, &RC[2]);
  1462. EXPECT_EQ(&AC, &RC[3]);
  1463. // Switch the ref edge from A -> D to a call edge. This should have no
  1464. // effect as it is already in postorder and no new cycles are formed.
  1465. EXPECT_FALSE(RC.switchInternalEdgeToCall(A, D));
  1466. ASSERT_EQ(4, RC.size());
  1467. EXPECT_EQ(&DC, &RC[0]);
  1468. EXPECT_EQ(&BC, &RC[1]);
  1469. EXPECT_EQ(&CC, &RC[2]);
  1470. EXPECT_EQ(&AC, &RC[3]);
  1471. // Switch B -> C to a call edge. This doesn't form any new cycles but does
  1472. // require reordering the SCCs.
  1473. EXPECT_FALSE(RC.switchInternalEdgeToCall(B, C));
  1474. ASSERT_EQ(4, RC.size());
  1475. EXPECT_EQ(&DC, &RC[0]);
  1476. EXPECT_EQ(&CC, &RC[1]);
  1477. EXPECT_EQ(&BC, &RC[2]);
  1478. EXPECT_EQ(&AC, &RC[3]);
  1479. // Switch C -> B to a call edge. This forms a cycle and forces merging SCCs.
  1480. EXPECT_TRUE(RC.switchInternalEdgeToCall(C, B, [&](ArrayRef<LazyCallGraph::SCC *> MergedCs) {
  1481. ASSERT_EQ(1u, MergedCs.size());
  1482. EXPECT_EQ(&CC, MergedCs[0]);
  1483. }));
  1484. ASSERT_EQ(3, RC.size());
  1485. EXPECT_EQ(&DC, &RC[0]);
  1486. EXPECT_EQ(&BC, &RC[1]);
  1487. EXPECT_EQ(&AC, &RC[2]);
  1488. EXPECT_EQ(2, BC.size());
  1489. EXPECT_EQ(&BC, CG.lookupSCC(B));
  1490. EXPECT_EQ(&BC, CG.lookupSCC(C));
  1491. }
  1492. TEST(LazyCallGraphTest, InternalRefEdgeToCallNoCycleInterleaved) {
  1493. LLVMContext Context;
  1494. // Test for having a post-order prior to changing a ref edge to a call edge
  1495. // with SCCs connecting to the source and connecting to the target, but not
  1496. // connecting to both, interleaved between the source and target. This
  1497. // ensures we correctly partition the range rather than simply moving one or
  1498. // the other.
  1499. std::unique_ptr<Module> M =
  1500. parseAssembly(Context, "define void @a() {\n"
  1501. "entry:\n"
  1502. " call void @b1()\n"
  1503. " call void @c1()\n"
  1504. " ret void\n"
  1505. "}\n"
  1506. "define void @b1() {\n"
  1507. "entry:\n"
  1508. " call void @c1()\n"
  1509. " call void @b2()\n"
  1510. " ret void\n"
  1511. "}\n"
  1512. "define void @c1() {\n"
  1513. "entry:\n"
  1514. " call void @b2()\n"
  1515. " call void @c2()\n"
  1516. " ret void\n"
  1517. "}\n"
  1518. "define void @b2() {\n"
  1519. "entry:\n"
  1520. " call void @c2()\n"
  1521. " call void @b3()\n"
  1522. " ret void\n"
  1523. "}\n"
  1524. "define void @c2() {\n"
  1525. "entry:\n"
  1526. " call void @b3()\n"
  1527. " call void @c3()\n"
  1528. " ret void\n"
  1529. "}\n"
  1530. "define void @b3() {\n"
  1531. "entry:\n"
  1532. " call void @c3()\n"
  1533. " call void @d()\n"
  1534. " ret void\n"
  1535. "}\n"
  1536. "define void @c3() {\n"
  1537. "entry:\n"
  1538. " store void()* @b1, void()** undef\n"
  1539. " call void @d()\n"
  1540. " ret void\n"
  1541. "}\n"
  1542. "define void @d() {\n"
  1543. "entry:\n"
  1544. " store void()* @a, void()** undef\n"
  1545. " ret void\n"
  1546. "}\n");
  1547. LazyCallGraph CG = buildCG(*M);
  1548. // Force the graph to be fully expanded.
  1549. CG.buildRefSCCs();
  1550. auto I = CG.postorder_ref_scc_begin();
  1551. LazyCallGraph::RefSCC &RC = *I++;
  1552. EXPECT_EQ(CG.postorder_ref_scc_end(), I);
  1553. LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
  1554. LazyCallGraph::Node &B1 = *CG.lookup(lookupFunction(*M, "b1"));
  1555. LazyCallGraph::Node &B2 = *CG.lookup(lookupFunction(*M, "b2"));
  1556. LazyCallGraph::Node &B3 = *CG.lookup(lookupFunction(*M, "b3"));
  1557. LazyCallGraph::Node &C1 = *CG.lookup(lookupFunction(*M, "c1"));
  1558. LazyCallGraph::Node &C2 = *CG.lookup(lookupFunction(*M, "c2"));
  1559. LazyCallGraph::Node &C3 = *CG.lookup(lookupFunction(*M, "c3"));
  1560. LazyCallGraph::Node &D = *CG.lookup(lookupFunction(*M, "d"));
  1561. LazyCallGraph::SCC &AC = *CG.lookupSCC(A);
  1562. LazyCallGraph::SCC &B1C = *CG.lookupSCC(B1);
  1563. LazyCallGraph::SCC &B2C = *CG.lookupSCC(B2);
  1564. LazyCallGraph::SCC &B3C = *CG.lookupSCC(B3);
  1565. LazyCallGraph::SCC &C1C = *CG.lookupSCC(C1);
  1566. LazyCallGraph::SCC &C2C = *CG.lookupSCC(C2);
  1567. LazyCallGraph::SCC &C3C = *CG.lookupSCC(C3);
  1568. LazyCallGraph::SCC &DC = *CG.lookupSCC(D);
  1569. // Several call edges are initially present to force a particual post-order.
  1570. // Remove them now, leaving an interleaved post-order pattern.
  1571. RC.switchTrivialInternalEdgeToRef(B3, C3);
  1572. RC.switchTrivialInternalEdgeToRef(C2, B3);
  1573. RC.switchTrivialInternalEdgeToRef(B2, C2);
  1574. RC.switchTrivialInternalEdgeToRef(C1, B2);
  1575. RC.switchTrivialInternalEdgeToRef(B1, C1);
  1576. // Check the initial post-order. We ensure this order with the extra edges
  1577. // that are nuked above.
  1578. ASSERT_EQ(8, RC.size());
  1579. EXPECT_EQ(&DC, &RC[0]);
  1580. EXPECT_EQ(&C3C, &RC[1]);
  1581. EXPECT_EQ(&B3C, &RC[2]);
  1582. EXPECT_EQ(&C2C, &RC[3]);
  1583. EXPECT_EQ(&B2C, &RC[4]);
  1584. EXPECT_EQ(&C1C, &RC[5]);
  1585. EXPECT_EQ(&B1C, &RC[6]);
  1586. EXPECT_EQ(&AC, &RC[7]);
  1587. // Switch C3 -> B1 to a call edge. This doesn't form any new cycles but does
  1588. // require reordering the SCCs in the face of tricky internal node
  1589. // structures.
  1590. EXPECT_FALSE(RC.switchInternalEdgeToCall(C3, B1));
  1591. ASSERT_EQ(8, RC.size());
  1592. EXPECT_EQ(&DC, &RC[0]);
  1593. EXPECT_EQ(&B3C, &RC[1]);
  1594. EXPECT_EQ(&B2C, &RC[2]);
  1595. EXPECT_EQ(&B1C, &RC[3]);
  1596. EXPECT_EQ(&C3C, &RC[4]);
  1597. EXPECT_EQ(&C2C, &RC[5]);
  1598. EXPECT_EQ(&C1C, &RC[6]);
  1599. EXPECT_EQ(&AC, &RC[7]);
  1600. }
  1601. TEST(LazyCallGraphTest, InternalRefEdgeToCallBothPartitionAndMerge) {
  1602. LLVMContext Context;
  1603. // Test for having a postorder where between the source and target are all
  1604. // three kinds of other SCCs:
  1605. // 1) One connected to the target only that have to be shifted below the
  1606. // source.
  1607. // 2) One connected to the source only that have to be shifted below the
  1608. // target.
  1609. // 3) One connected to both source and target that has to remain and get
  1610. // merged away.
  1611. //
  1612. // To achieve this we construct a heavily connected graph to force
  1613. // a particular post-order. Then we remove the forcing edges and connect
  1614. // a cycle.
  1615. //
  1616. // Diagram for the graph we want on the left and the graph we use to force
  1617. // the ordering on the right. Edges ponit down or right.
  1618. //
  1619. // A | A |
  1620. // / \ | / \ |
  1621. // B E | B \ |
  1622. // |\ | | |\ | |
  1623. // | D | | C-D-E |
  1624. // | \| | | \| |
  1625. // C F | \ F |
  1626. // \ / | \ / |
  1627. // G | G |
  1628. //
  1629. // And we form a cycle by connecting F to B.
  1630. std::unique_ptr<Module> M =
  1631. parseAssembly(Context, "define void @a() {\n"
  1632. "entry:\n"
  1633. " call void @b()\n"
  1634. " call void @e()\n"
  1635. " ret void\n"
  1636. "}\n"
  1637. "define void @b() {\n"
  1638. "entry:\n"
  1639. " call void @c()\n"
  1640. " call void @d()\n"
  1641. " ret void\n"
  1642. "}\n"
  1643. "define void @c() {\n"
  1644. "entry:\n"
  1645. " call void @d()\n"
  1646. " call void @g()\n"
  1647. " ret void\n"
  1648. "}\n"
  1649. "define void @d() {\n"
  1650. "entry:\n"
  1651. " call void @e()\n"
  1652. " call void @f()\n"
  1653. " ret void\n"
  1654. "}\n"
  1655. "define void @e() {\n"
  1656. "entry:\n"
  1657. " call void @f()\n"
  1658. " ret void\n"
  1659. "}\n"
  1660. "define void @f() {\n"
  1661. "entry:\n"
  1662. " store void()* @b, void()** undef\n"
  1663. " call void @g()\n"
  1664. " ret void\n"
  1665. "}\n"
  1666. "define void @g() {\n"
  1667. "entry:\n"
  1668. " store void()* @a, void()** undef\n"
  1669. " ret void\n"
  1670. "}\n");
  1671. LazyCallGraph CG = buildCG(*M);
  1672. // Force the graph to be fully expanded.
  1673. CG.buildRefSCCs();
  1674. auto I = CG.postorder_ref_scc_begin();
  1675. LazyCallGraph::RefSCC &RC = *I++;
  1676. EXPECT_EQ(CG.postorder_ref_scc_end(), I);
  1677. LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
  1678. LazyCallGraph::Node &B = *CG.lookup(lookupFunction(*M, "b"));
  1679. LazyCallGraph::Node &C = *CG.lookup(lookupFunction(*M, "c"));
  1680. LazyCallGraph::Node &D = *CG.lookup(lookupFunction(*M, "d"));
  1681. LazyCallGraph::Node &E = *CG.lookup(lookupFunction(*M, "e"));
  1682. LazyCallGraph::Node &F = *CG.lookup(lookupFunction(*M, "f"));
  1683. LazyCallGraph::Node &G = *CG.lookup(lookupFunction(*M, "g"));
  1684. LazyCallGraph::SCC &AC = *CG.lookupSCC(A);
  1685. LazyCallGraph::SCC &BC = *CG.lookupSCC(B);
  1686. LazyCallGraph::SCC &CC = *CG.lookupSCC(C);
  1687. LazyCallGraph::SCC &DC = *CG.lookupSCC(D);
  1688. LazyCallGraph::SCC &EC = *CG.lookupSCC(E);
  1689. LazyCallGraph::SCC &FC = *CG.lookupSCC(F);
  1690. LazyCallGraph::SCC &GC = *CG.lookupSCC(G);
  1691. // Remove the extra edges that were used to force a particular post-order.
  1692. RC.switchTrivialInternalEdgeToRef(C, D);
  1693. RC.switchTrivialInternalEdgeToRef(D, E);
  1694. // Check the initial post-order. We ensure this order with the extra edges
  1695. // that are nuked above.
  1696. ASSERT_EQ(7, RC.size());
  1697. EXPECT_EQ(&GC, &RC[0]);
  1698. EXPECT_EQ(&FC, &RC[1]);
  1699. EXPECT_EQ(&EC, &RC[2]);
  1700. EXPECT_EQ(&DC, &RC[3]);
  1701. EXPECT_EQ(&CC, &RC[4]);
  1702. EXPECT_EQ(&BC, &RC[5]);
  1703. EXPECT_EQ(&AC, &RC[6]);
  1704. // Switch F -> B to a call edge. This merges B, D, and F into a single SCC,
  1705. // and has to place the C and E SCCs on either side of it:
  1706. // A A |
  1707. // / \ / \ |
  1708. // B E | E |
  1709. // |\ | \ / |
  1710. // | D | -> B |
  1711. // | \| / \ |
  1712. // C F C | |
  1713. // \ / \ / |
  1714. // G G |
  1715. EXPECT_TRUE(RC.switchInternalEdgeToCall(
  1716. F, B, [&](ArrayRef<LazyCallGraph::SCC *> MergedCs) {
  1717. ASSERT_EQ(2u, MergedCs.size());
  1718. EXPECT_EQ(&FC, MergedCs[0]);
  1719. EXPECT_EQ(&DC, MergedCs[1]);
  1720. }));
  1721. EXPECT_EQ(3, BC.size());
  1722. // And make sure the postorder was updated.
  1723. ASSERT_EQ(5, RC.size());
  1724. EXPECT_EQ(&GC, &RC[0]);
  1725. EXPECT_EQ(&CC, &RC[1]);
  1726. EXPECT_EQ(&BC, &RC[2]);
  1727. EXPECT_EQ(&EC, &RC[3]);
  1728. EXPECT_EQ(&AC, &RC[4]);
  1729. }
  1730. // Test for IR containing constants using blockaddress constant expressions.
  1731. // These are truly unique constructs: constant expressions with non-constant
  1732. // operands.
  1733. TEST(LazyCallGraphTest, HandleBlockAddress) {
  1734. LLVMContext Context;
  1735. std::unique_ptr<Module> M =
  1736. parseAssembly(Context, "define void @f() {\n"
  1737. "entry:\n"
  1738. " ret void\n"
  1739. "bb:\n"
  1740. " unreachable\n"
  1741. "}\n"
  1742. "define void @g(i8** %ptr) {\n"
  1743. "entry:\n"
  1744. " store i8* blockaddress(@f, %bb), i8** %ptr\n"
  1745. " ret void\n"
  1746. "}\n");
  1747. LazyCallGraph CG = buildCG(*M);
  1748. CG.buildRefSCCs();
  1749. auto I = CG.postorder_ref_scc_begin();
  1750. LazyCallGraph::RefSCC &FRC = *I++;
  1751. LazyCallGraph::RefSCC &GRC = *I++;
  1752. EXPECT_EQ(CG.postorder_ref_scc_end(), I);
  1753. LazyCallGraph::Node &F = *CG.lookup(lookupFunction(*M, "f"));
  1754. LazyCallGraph::Node &G = *CG.lookup(lookupFunction(*M, "g"));
  1755. EXPECT_EQ(&FRC, CG.lookupRefSCC(F));
  1756. EXPECT_EQ(&GRC, CG.lookupRefSCC(G));
  1757. EXPECT_TRUE(GRC.isParentOf(FRC));
  1758. }
  1759. TEST(LazyCallGraphTest, ReplaceNodeFunction) {
  1760. LLVMContext Context;
  1761. // A graph with several different kinds of edges pointing at a particular
  1762. // function.
  1763. std::unique_ptr<Module> M =
  1764. parseAssembly(Context,
  1765. "define void @a(i8** %ptr) {\n"
  1766. "entry:\n"
  1767. " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
  1768. " ret void\n"
  1769. "}\n"
  1770. "define void @b(i8** %ptr) {\n"
  1771. "entry:\n"
  1772. " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
  1773. " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
  1774. " call void @d(i8** %ptr)"
  1775. " ret void\n"
  1776. "}\n"
  1777. "define void @c(i8** %ptr) {\n"
  1778. "entry:\n"
  1779. " call void @d(i8** %ptr)"
  1780. " call void @d(i8** %ptr)"
  1781. " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
  1782. " ret void\n"
  1783. "}\n"
  1784. "define void @d(i8** %ptr) {\n"
  1785. "entry:\n"
  1786. " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
  1787. " call void @c(i8** %ptr)"
  1788. " call void @d(i8** %ptr)"
  1789. " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
  1790. " ret void\n"
  1791. "}\n");
  1792. LazyCallGraph CG = buildCG(*M);
  1793. // Force the graph to be fully expanded.
  1794. CG.buildRefSCCs();
  1795. auto I = CG.postorder_ref_scc_begin();
  1796. LazyCallGraph::RefSCC &RC1 = *I++;
  1797. LazyCallGraph::RefSCC &RC2 = *I++;
  1798. EXPECT_EQ(CG.postorder_ref_scc_end(), I);
  1799. ASSERT_EQ(2, RC1.size());
  1800. LazyCallGraph::SCC &C1 = RC1[0];
  1801. LazyCallGraph::SCC &C2 = RC1[1];
  1802. LazyCallGraph::Node &AN = *CG.lookup(lookupFunction(*M, "a"));
  1803. LazyCallGraph::Node &BN = *CG.lookup(lookupFunction(*M, "b"));
  1804. LazyCallGraph::Node &CN = *CG.lookup(lookupFunction(*M, "c"));
  1805. LazyCallGraph::Node &DN = *CG.lookup(lookupFunction(*M, "d"));
  1806. EXPECT_EQ(&C1, CG.lookupSCC(DN));
  1807. EXPECT_EQ(&C1, CG.lookupSCC(CN));
  1808. EXPECT_EQ(&C2, CG.lookupSCC(BN));
  1809. EXPECT_EQ(&RC1, CG.lookupRefSCC(DN));
  1810. EXPECT_EQ(&RC1, CG.lookupRefSCC(CN));
  1811. EXPECT_EQ(&RC1, CG.lookupRefSCC(BN));
  1812. EXPECT_EQ(&RC2, CG.lookupRefSCC(AN));
  1813. // Now we need to build a new function 'e' with the same signature as 'd'.
  1814. Function &D = DN.getFunction();
  1815. Function &E = *Function::Create(D.getFunctionType(), D.getLinkage(), "e");
  1816. D.getParent()->getFunctionList().insert(D.getIterator(), &E);
  1817. // Change each use of 'd' to use 'e'. This is particularly easy as they have
  1818. // the same type.
  1819. D.replaceAllUsesWith(&E);
  1820. // Splice the body of the old function into the new one.
  1821. E.getBasicBlockList().splice(E.begin(), D.getBasicBlockList());
  1822. // And fix up the one argument.
  1823. D.arg_begin()->replaceAllUsesWith(&*E.arg_begin());
  1824. E.arg_begin()->takeName(&*D.arg_begin());
  1825. // Now replace the function in the graph.
  1826. RC1.replaceNodeFunction(DN, E);
  1827. EXPECT_EQ(&E, &DN.getFunction());
  1828. EXPECT_EQ(&DN, &(*CN)[DN].getNode());
  1829. EXPECT_EQ(&DN, &(*BN)[DN].getNode());
  1830. }
  1831. TEST(LazyCallGraphTest, RemoveFunctionWithSpurriousRef) {
  1832. LLVMContext Context;
  1833. // A graph with a couple of RefSCCs.
  1834. std::unique_ptr<Module> M =
  1835. parseAssembly(Context,
  1836. "define void @a(i8** %ptr) {\n"
  1837. "entry:\n"
  1838. " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
  1839. " ret void\n"
  1840. "}\n"
  1841. "define void @b(i8** %ptr) {\n"
  1842. "entry:\n"
  1843. " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
  1844. " ret void\n"
  1845. "}\n"
  1846. "define void @c(i8** %ptr) {\n"
  1847. "entry:\n"
  1848. " call void @d(i8** %ptr)"
  1849. " ret void\n"
  1850. "}\n"
  1851. "define void @d(i8** %ptr) {\n"
  1852. "entry:\n"
  1853. " call void @c(i8** %ptr)"
  1854. " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
  1855. " ret void\n"
  1856. "}\n"
  1857. "define void @dead() {\n"
  1858. "entry:\n"
  1859. " ret void\n"
  1860. "}\n");
  1861. LazyCallGraph CG = buildCG(*M);
  1862. // Insert spurious ref edges.
  1863. LazyCallGraph::Node &AN = CG.get(lookupFunction(*M, "a"));
  1864. LazyCallGraph::Node &BN = CG.get(lookupFunction(*M, "b"));
  1865. LazyCallGraph::Node &CN = CG.get(lookupFunction(*M, "c"));
  1866. LazyCallGraph::Node &DN = CG.get(lookupFunction(*M, "d"));
  1867. LazyCallGraph::Node &DeadN = CG.get(lookupFunction(*M, "dead"));
  1868. AN.populate();
  1869. BN.populate();
  1870. CN.populate();
  1871. DN.populate();
  1872. DeadN.populate();
  1873. CG.insertEdge(AN, DeadN, LazyCallGraph::Edge::Ref);
  1874. CG.insertEdge(BN, DeadN, LazyCallGraph::Edge::Ref);
  1875. CG.insertEdge(CN, DeadN, LazyCallGraph::Edge::Ref);
  1876. CG.insertEdge(DN, DeadN, LazyCallGraph::Edge::Ref);
  1877. // Force the graph to be fully expanded.
  1878. CG.buildRefSCCs();
  1879. auto I = CG.postorder_ref_scc_begin();
  1880. LazyCallGraph::RefSCC &DeadRC = *I++;
  1881. LazyCallGraph::RefSCC &RC1 = *I++;
  1882. LazyCallGraph::RefSCC &RC2 = *I++;
  1883. EXPECT_EQ(CG.postorder_ref_scc_end(), I);
  1884. ASSERT_EQ(2, RC1.size());
  1885. LazyCallGraph::SCC &C1 = RC1[0];
  1886. LazyCallGraph::SCC &C2 = RC1[1];
  1887. EXPECT_EQ(&DeadRC, CG.lookupRefSCC(DeadN));
  1888. EXPECT_EQ(&C1, CG.lookupSCC(DN));
  1889. EXPECT_EQ(&C1, CG.lookupSCC(CN));
  1890. EXPECT_EQ(&C2, CG.lookupSCC(BN));
  1891. EXPECT_EQ(&RC1, CG.lookupRefSCC(DN));
  1892. EXPECT_EQ(&RC1, CG.lookupRefSCC(CN));
  1893. EXPECT_EQ(&RC1, CG.lookupRefSCC(BN));
  1894. EXPECT_EQ(&RC2, CG.lookupRefSCC(AN));
  1895. // Now delete 'dead'. There are no uses of this function but there are
  1896. // spurious references.
  1897. CG.removeDeadFunction(DeadN.getFunction());
  1898. // The only observable change should be that the RefSCC is gone from the
  1899. // postorder sequence.
  1900. I = CG.postorder_ref_scc_begin();
  1901. EXPECT_EQ(&RC1, &*I++);
  1902. EXPECT_EQ(&RC2, &*I++);
  1903. EXPECT_EQ(CG.postorder_ref_scc_end(), I);
  1904. }
  1905. }