From 02940d6d22022dbad45efa0c9a5cc772ba844da4 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Tue, 7 Dec 2021 10:50:08 -0800 Subject: [PATCH] Revert "CycleInfo: Introduce cycles as a generalization of loops" This reverts commit 0fe61ecc2cef333250a152cd90d80d0b802b27db because it breaks the modules build. https://green.lab.llvm.org/green/job/clang-stage2-rthinlto/4858/ https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/39112/ --- llvm/docs/CycleTerminology.rst | 228 ------- llvm/docs/UserGuides.rst | 4 - llvm/docs/cycle-1.png | Bin 18190 -> 0 bytes llvm/docs/cycle-2.png | Bin 17548 -> 0 bytes llvm/docs/cycle-3.png | Bin 18776 -> 0 bytes llvm/include/llvm/ADT/GenericCycleImpl.h | 409 ------------ llvm/include/llvm/ADT/GenericCycleInfo.h | 339 ---------- llvm/include/llvm/ADT/GenericSSAContext.h | 74 --- llvm/include/llvm/Analysis/CycleAnalysis.h | 77 --- .../llvm/CodeGen/MachineCycleAnalysis.h | 63 -- .../llvm/CodeGen/MachinePassRegistry.def | 2 - llvm/include/llvm/CodeGen/MachineSSAContext.h | 58 -- llvm/include/llvm/IR/SSAContext.h | 56 -- llvm/include/llvm/InitializePasses.h | 3 - llvm/lib/Analysis/Analysis.cpp | 1 - llvm/lib/Analysis/CMakeLists.txt | 1 - llvm/lib/Analysis/CycleAnalysis.cpp | 77 --- llvm/lib/CodeGen/CMakeLists.txt | 2 - llvm/lib/CodeGen/CodeGen.cpp | 2 - llvm/lib/CodeGen/MachineCycleAnalysis.cpp | 87 --- llvm/lib/CodeGen/MachineSSAContext.cpp | 52 -- llvm/lib/IR/CMakeLists.txt | 1 - llvm/lib/IR/SSAContext.cpp | 47 -- llvm/lib/Passes/PassBuilder.cpp | 1 - llvm/lib/Passes/PassRegistry.def | 2 - llvm/test/Analysis/CycleInfo/basic.ll | 302 --------- llvm/test/CodeGen/X86/cycle-info.mir | 629 ------------------ 27 files changed, 2517 deletions(-) delete mode 100644 llvm/docs/CycleTerminology.rst delete mode 100644 llvm/docs/cycle-1.png delete mode 100644 llvm/docs/cycle-2.png delete mode 100644 llvm/docs/cycle-3.png delete mode 100644 llvm/include/llvm/ADT/GenericCycleImpl.h delete mode 100644 llvm/include/llvm/ADT/GenericCycleInfo.h delete mode 100644 llvm/include/llvm/ADT/GenericSSAContext.h delete mode 100644 llvm/include/llvm/Analysis/CycleAnalysis.h delete mode 100644 llvm/include/llvm/CodeGen/MachineCycleAnalysis.h delete mode 100644 llvm/include/llvm/CodeGen/MachineSSAContext.h delete mode 100644 llvm/include/llvm/IR/SSAContext.h delete mode 100644 llvm/lib/Analysis/CycleAnalysis.cpp delete mode 100644 llvm/lib/CodeGen/MachineCycleAnalysis.cpp delete mode 100644 llvm/lib/CodeGen/MachineSSAContext.cpp delete mode 100644 llvm/lib/IR/SSAContext.cpp delete mode 100644 llvm/test/Analysis/CycleInfo/basic.ll delete mode 100644 llvm/test/CodeGen/X86/cycle-info.mir diff --git a/llvm/docs/CycleTerminology.rst b/llvm/docs/CycleTerminology.rst deleted file mode 100644 index 3d7c397f13a8..000000000000 --- a/llvm/docs/CycleTerminology.rst +++ /dev/null @@ -1,228 +0,0 @@ -.. _cycle-terminology: - -====================== -LLVM Cycle Terminology -====================== - -.. contents:: - :local: - -Cycles -====== - -Cycles are a generalization of LLVM :ref:`loops `, -defined recursively as follows [HavlakCycles]_: - -1. In a directed graph G, an *outermost cycle* is a maximal strongly - connected region with at least one internal edge. (Informational - note --- The requirement for at least one internal edge ensures - that a single basic block is a cycle only if there is an edge that - goes back to the same basic block.) -2. A basic block in the cycle that can be reached from the entry of - the function along a path that does not visit any other basic block - in the cycle is called an *entry* of the cycle. A cycle can have - multiple entries. -3. In any depth-first search starting from the entry of the function, - the first node of a cycle to be visited will be one of the entries. - This entry is called the *header* of the cycle. (Informational note - --- Thus, the header of the cycle is implementation-defined.) -4. In any depth-first search starting from the entry, set of outermost - cycles found in the CFG is the same. These are the *top-level - cycles* that do not themselves have a parent. -5. The cycles nested inside a cycle C with header H are the outermost - cycles in the subgraph induced on the set of nodes (C - H). C is - said to be the *parent* of these cycles, and each of these cycles - is a *child* of C. - -Thus, cycles form an implementation-defined forest where each cycle C is -the parent of any outermost cycles nested inside C. The tree closely -follows the nesting of loops in the same function. The unique entry of -a reducible cycle (an LLVM loop) L dominates all its other nodes, and -is always chosen as the header of some cycle C regardless of the DFS -tree used. This cycle C is a superset of the loop L. For an -irreducible cycle, no one entry dominates the nodes of the cycle. One -of the entries is chosen as header of the cycle, in an -implementation-defined way. - -.. _cycle-irreducible: - -A cycle is *irreducible* if it has multiple entries and it is -*reducible* otherwise. - -.. _cycle-parent-block: - -A cycle C is said to be the *parent* of a basic block B if B occurs in -C but not in any child cycle of C. Then B is also said to be a *child* -of cycle C. - -.. _cycle-sibling: - -A basic block or cycle X is a *sibling* of another basic block or -cycle Y if they both have no parent or both have the same parent. - -Informational notes: - -- Non-header entry blocks of a cycle can be contained in child cycles. -- If the CFG is reducible, the cycles are exactly the natural loops and - every cycle has exactly one entry block. -- Cycles are well-nested (by definition). -- The entry blocks of a cycle are siblings in the dominator tree. - -.. [HavlakCycles] Paul Havlak, "Nesting of reducible and irreducible - loops." ACM Transactions on Programming Languages - and Systems (TOPLAS) 19.4 (1997): 557-567. - -.. _cycle-examples: - -Examples of Cycles -================== - -Irreducible cycle enclosing natural loops ------------------------------------------ - -.. Graphviz source; the indented blocks below form a comment. - - /// | | - /// />A] [B<\ - /// | \ / | - /// ^---C---^ - /// | - - strict digraph { - { rank=same; A B} - Entry -> A - Entry -> B - A -> A - A -> C - B -> B - B -> C - C -> A - C -> B - C -> Exit - } - -.. image:: cycle-1.png - -The self-loops of ``A`` and ``B`` give rise to two single-block -natural loops. A possible hierarchy of cycles is:: - - cycle: {A, B, C} entries: {A, B} header: A - - cycle: {B, C} entries: {B, C} header: C - - cycle: {B} entries: {B} header: B - -This hierarchy arises when DFS visits the blocks in the order ``A``, -``C``, ``B`` (in preorder). - -Irreducible union of two natural loops --------------------------------------- - -.. Graphviz source; the indented blocks below form a comment. - - /// | | - /// A<->B - /// ^ ^ - /// | | - /// v v - /// C D - /// | | - - strict digraph { - { rank=same; A B} - { rank=same; C D} - Entry -> A - Entry -> B - A -> B - B -> A - A -> C - C -> A - B -> D - D -> B - C -> Exit - D -> Exit - } - -.. image:: cycle-2.png - -There are two natural loops: ``{A, C}`` and ``{B, D}``. A possible -hierarchy of cycles is:: - - cycle: {A, B, C, D} entries: {A, B} header: A - - cycle: {B, D} entries: {B} header: B - -Irreducible cycle without natural loops ---------------------------------------- - -.. Graphviz source; the indented blocks below form a comment. - - /// | | - /// />A B<\ - /// | |\ /| | - /// | | x | | - /// | |/ \| | - /// ^-C D-^ - /// | | - /// - - strict digraph { - { rank=same; A B} - { rank=same; C D} - Entry -> A - Entry -> B - A -> C - A -> D - B -> C - B -> D - C -> A - D -> B - C -> Exit - D -> Exit - } - -.. image:: cycle-3.png - -This graph does not contain any natural loops --- the nodes ``A``, -``B``, ``C`` and ``D`` are siblings in the dominator tree. A possible -hierarchy of cycles is:: - - cycle: {A, B, C, D} entries: {A, B} header: A - - cycle: {B, D} entries: {B, D} header: D - -.. _cycle-closed-path: - -Closed Paths and Cycles -======================= - -A *closed path* in a CFG is a connected sequence of nodes and edges in -the CFG whose start and end points are the same. - -1. If a node D dominates one or more nodes in a closed path P and P - does not contain D, then D dominates every node in P. - - **Proof:** Let U be a node in P that is dominated by D. If there - was a node V in P not dominated by D, then U would be reachable - from the function entry node via V without passing through D, which - contradicts the fact that D dominates U. - -2. If a node D dominates one or more nodes in a closed path P and P - does not contain D, then there exists a cycle C that contains P but - not D. - - **Proof:** From the above property, D dominates all the nodes in P. - For any nesting of cycles discovered by the implementation-defined - DFS, consider the smallest cycle C which contains P. For the sake - of contradiction, assume that D is in C. Then the header H of C - cannot be in P, since the header of a cycle cannot be dominated by - any other node in the cycle. Thus, P is in the set (C-H), and there - must be a smaller cycle C' in C which also contains P, but that - contradicts how we chose C. - -3. If a closed path P contains nodes U1 and U2 but not their - dominators D1 and D2 respectively, then there exists a cycle C that - contains U1 and U2 but neither of D1 and D2. - - **Proof:** From the above properties, each D1 and D2 separately - dominate every node in P. There exists a cycle C1 (respectively, - C2) that contains P but not D1 (respectively, D2). Either C1 and C2 - are the same cycle, or one of them is nested inside the other. - Hence there is always a cycle that contains U1 and U2 but neither - of D1 and D2. diff --git a/llvm/docs/UserGuides.rst b/llvm/docs/UserGuides.rst index 1446e3bf5553..29d16c0700b9 100644 --- a/llvm/docs/UserGuides.rst +++ b/llvm/docs/UserGuides.rst @@ -27,7 +27,6 @@ intermediate LLVM representation. CommandLine CompileCudaWithLLVM CoverageMappingFormat - CycleTerminology DebuggingJITedCode Docker ExtendingLLVM @@ -138,9 +137,6 @@ Optimizations :doc:`LoopTerminology` A document describing Loops and associated terms as used in LLVM. -:doc:`CycleTerminology` - A document describing cycles as a generalization of loops. - :doc:`Vectorizers` This document describes the current status of vectorization in LLVM. diff --git a/llvm/docs/cycle-1.png b/llvm/docs/cycle-1.png deleted file mode 100644 index 42efda3a21ed145617d181e00177e3fe25fdb59b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18190 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

2jd~ZV%DaqC zq2T`gr>uI4AAR)=Rn^faPoAUF%g||sppEc1d~WLBo7&PTg;Vng87jwq5<+7fh?E-5 zmR)I(P_Go_;YeIDGAKMeCQA1HUK3h6SAl-k+~=wXKDF;&*?m#d$-WC3twuCCv{k%q*Z1;M1fxD-B*}{fW?-l9wxjbJU^bSnCep8J!r!t~cE=$%5;^e+XV`CbEgBf7p z`8U_>G6H`CwG}%IP#~!W18NaMAJI~tHn(^$ZP$~A?C0R<=nuKY$jGQA>&zaKAMhz9 zg}*1)5r}fglRVIkf#&>lvY(zwJ%50@K0g7COQL&(ZYqVCFj?x6*$PRBmCo>mIo0P+ zpR^$mStG-#70B}K-ye>Sj1qXp(9fS2N2@|0sXuu5P*76xZu!#4PL4y@4wS9Uf9c3L z#df9h#fgjF|LFyIvhDMiFEM3hWy`DGZEbgc{QOz>`Ew%l4MA>hKUBoClQze|hsUAA zp1mS=nVh3^=t3r{Un}qh@^o}&CVya15XX;;IcW9(d+f%8-3|}m{0wcn0_SGPWp`A0 zvso`eU=}tkOq-r|i0lzx(NgW{?f8Q|mqd&K6b|+GE8(b1hBR6L%W=v%-3(&bsivHM z8v$Vr?xLrsSCgHK{VA$CmZr)J$g&xL=}cLb_4jpK-{5n+4dEw2>z+@aKl6x*F+oxt>&RvyBp965t~a-wN1KlF z#iSz|PnGoFtNJh8XRHm@uQ{SO`i0b1xJU~rw? z-8pQCv9|zHJln%vd)b=Ty6qE8j`76|AW1AP4&D;?S#<|6IqdO=67b+db91nf$Z?=J zY|lUc{KLIH+|1TCTrH9#-JrnI!P&Vwl!bqKsE%cqtOH3Uh+h2TxL|I7BAMY{QaknV z@P)~O+A1hnCk0ryR*TKn@u!X{agqn3$!FsWJNZFnZ=cxvyr3Xw#!4$io+?(Iinl6? z^N@?7ba>u$oo@hb0S**Q}B@$!L2F(RUHpzvxkeWPc12BV z0TXT}f+Y9cvD}KUe8@2K!s5M9Vzy4U11KrPJy+a-M;W3oOZp-G34Z+5@^jr zu}?Jjs5m-`H>E1(^+xqy1{udQ;BTU<1?P#4uE3=UfpT0ca6Zgayv0`6UZfPpfc$# zB(x|f;HF5m@~w6Hiz5}Skqu{sL!wXYo%r&^QZm?n-PyCrNI{}w?#l966p5n=HvddF z`f64mh_By}R=N2#!{tk2(u*UCnILxCNgbocbG6zHlK=jnbJ=>NMT^HTDrLxxX3}Q3 z`_Y?Aot^rw|9OdhQ(`^;pGNB~eXBAd(Ix4YPxPKp-x7ID+qXJ;EWsd7iuPb6L-~?D zliAfQW-L)9nfve0BpZhL;!@vqvZ?IY5rGSuvv2&N>SZW%7i0bV0pj-*yu+`~PKKxN z8u@#LO+tM)rKC$#o3*o_xP>`Jd4UZ*46Gwn|H_!JWRB>DS{Ew zAdZR9SAW0|_sM6kCOWR7rGTX$oBrlo7PJHbKBwqJs!nzd*z06RF5Z!zvwS75TkO={ ztwd`vCt&JXN07T1mutpnkPTr&*KOzN)wI}pHBqs+N?A=O;nYvmm z28M@sf!ekj)?(M-lcY4jFrazI+Y!L_kM~CS>8fi?NoRMHM z)t^7_00o_R-zQbs*0xndLcrUtS6m#C{h22T<)>9ToBM z@tLvfICcbNgum_>KFojU&>?g7AbGc68iW#X#N&_Z{x$Z^d?UWaUDZa~+Den%dHg0O zCKO8O(-&T<+xpsZFzDr*C)-MlG+`r?^!RfL@+=%2s#B#iTd)BdQ--sFn^yA5#Ms~m zfOY`^ClbwE8z|*2tBa0yQhla4{BRiPLYW1e1pj^rcwuf3XKQ0v`J-Zc)l;2pYpA~< zb0=^(ALNxUhh36Ll&%?%01j+N?IS+5u#gF~mbzZHD|1tmRat%dgQA2i&;oVeCaYOI3mMibq@ zp{Xf*7q*jg!$>5T?Cee>s}HSeU!6DEL$>{2OEpcB|F=|{%ngo?j*cZz*O$qR?J;8Tm-ouU-`bCgLYadM!GXHBVdj`*xZsc+LuJNJIA!_t^He z+?zObWyqLP>%Aq;qqDm$c^}|JMCat}7i6VNnXir|7X>C>Hkjxs+P@(U?ZC0KJI_2@ z57uAm?}8Z1%)~?z6&2-FVAoE>v-w>%AnaK0`Zm+jl9%Ix@Na22_{&QX3$*Hx!QcC>YyCf2zm`lzRI{4G5 zNNDs2^{#ZW!ea<)!+(74&rGMEpP!KJ;mM?=)jZabKN6<^_u8L55n3FI(c<13`Wym1 zhp#=Fy{OeNTtwZ!yXJdI!XTx-yo(C*9btcizlB7!hvZtdW5}^pMn3NQMME;Rdhin1 zy8+Zb=x^6!D`M{6y@`W3_|2_v_|n9a(p|B+{cYr)#qZ&wOl)kyZoM9vUE{hJ&)_C} zSB@M$On7y3^z*9Tzdt_u-FP@BuUr{`96bC69J(6GvdrMhYS*qwudlDzd%T}1l3o?eUu5#85J84S3IB*Jdst_<0r!kP+DJ%)3vj^Yx zHx|pi4DynUGq#g+%2U=l^-Tx|62q?@vbl2J%Me;%;+`nvLT1zrC!Y7~ zzdbo9L3}4-xz$6_lAQAxcQB#offbiS)*lb zN@_uoa(&qJfpBjYUHz5>$Ix6`>SuBo0<7`YX@;HB5kz8r^hkAOA|eD47^5xl2q$u~ z$fSTQ+R{Q!s!oP03JsUp&sM26`YFtyR!Y#sB&}Px%S2DeteEhVZGGhr9XJqy$3-jm zidK4b8fwkZhiIa+1B#JsEk;PyN!$Dr<(&BlGamR6M{Y|<0x}e`TN~^WvYlo`#+BM! zpq}vn4wd|(q6}EEq&3o+0qq(S4+g^#z$xz%Vk-wVNM***8C?ZJu*`q{JPls<p5guC5a%e%8|ztM5BOPEmLkRw`O_4(wy zy0@uk1esFOWlWnw2~Yd@`*(AgqHlgCt4sc)#R6k5su(w7ifD&G46e7{{vP|(3J^@F zZKY*pa{D7bF+p$pKi3i7jWr)>TxW@XDN|H>eL>`Of|x%#wQ{nuEvR1%-&b{^RKfgi z4W}nmE&?W;%QdPy*(iC@{C}ek%w1#uZ*>8=3t#g@H9E)+DOV|*^ADI?SU67iAKfMI zLW^GG4M;Z>8#gk;T@Ta-fV^d5>&Cfba1%n)_}@wZUgCQyYgYR*+r=u>m6a)=(>Ow? zf-yg9KRaG44HOQPS_Os!!Zih8b^iSMw{Vt%@(TzEKp#>)dUONePIO#c5bOhw9zW)V zMnxA$f$0F0eOfv?!nVrH%1SuEyuFVEWPT+I8C)s@$hxG$N%H?x1Wxp=Ps%jp@y65< zzA2{)z zg2DlrE%6rl^AejSiFVVbN(^S)PDsdF$bS{o0DommiL({4_VD2w)wfEo($64b2Y&vH zL=)HyQkzk|ID60*&M;JHSd@3VIDYi3Y8Ko07Huj=w2t=f+jo>V8eSRa|EH-7-gA+D z`vk5do;N{&2IEb9Dq%QoDB9JuL(G(fUZIPzK#I!ZPD>IIxV(GzL?VWN^Apb@4eGzl3s0*nYZoW`j=N+(9B--Tq2`kW^q( z8qLxZBDx(@WedB}^Cs?VCSmrnpr9J?;JIZZ2cq3k_;@BHUK-e#`J{w4@;NmT7@ry6 zOi1c@;$&Mn`J)*+l`tRx9iVN4cT^CMbRKbfq$3EO^;W9yy1|+$sgE#cfHwVxOTt0yjlC;r`jm0HcHs#{>!nYD|#-^7+~V>Bt(Wo z)X7^7evWw}2Wvb1q)dDE93+X+2kbi)*AKNWBs_c&wy;G^DS$mTVYY%&`ItD6J#^?^_?OZf9+!NmRPt6Way#^dS4Ajvx#-LI?v(@? z7bR31ZIe1%e?UYe2+hkTDZS2HC9iEFf3(+8A9>e=emv+F0iQdj_U+wE0Q+(LrYk&% z@SX$J3W$not@YAyc`2b)mYJU~QD!YB;ZpF0l?$ruUe~b}|6gBARLINS6&Uvc)kOYv z?R5j**}xrS_MxjQ4#-*!BmxeuF|1>^2U#ubs@pvYOU-0ie^|z{W$wd6O(G#@9rj+< z%k(xWcEIV|Fj28NP&uU5Tvk?=7!!bDBXe!1;7E3fK77MfC|qJNn&Z?zKajIUf^^B! z@&TYjCI=F|zF7q`oIdcr5dRk*%=6`5a)2AIPb%5PgO_}v30T0W0G0WR;N6;$~ZB$V_yBAyHAe(lw$n zckVpU6&4f})E0{ETu;7ifVW_U7#E-|(2>2}qH5O&8QxhxH1l``1hU?7K7r?=soD#c zBE#cf0R;Nd&FRkGVo|+oB>uK~20Ff~u;g6X^?O!aLZ7Ny4A9@U>uDt@L7FbZyAZjC zJfdk^vA(<+N%t(ZVY>F%Y+@zq!O-yV*`x|0LyQz(Zd0N;_*ylEf;GXzOoN00M8rqcE_rz$R9}yG~ zDxQg%pL3N@W59q8kQp~Cof+N*l14i4yZm^#eS+J`?%N1U4$KM=&u~<=7)BWCExXPS zxIs_9egA$G-t;hJt+(N?;lZndT7%Mx-GELV00j)`cfZ|B55lGts}AqlAVy2v0lMer zIU_lp6DHpl+Oz}45o1yPP~M7NC%0oP==PmEHzFb;Jim=xb8t|K;X4gy)h2kiP*ld5asc(&no-LlP3uU2r|!6RWuRQ zV3ux$Z3E+kY-kYhm0ixKPGB3=uLYrC+PympRt=*PCn`*1!Z`&es1oSG>uW#5VCIJD z>}bx~$jHcptSnlh0p|XjmuP?iRu7_OgmXr?+tADj0xEw9?b-0>JsNDk=GChr*QR@!*fg3}2gxEotsW2)c7^|L}akdT*V1w7{z^Dvz1xk+%(5T+|^B;;NbH%^$pWc1g zT?zIO0LE-|<_b|s{*K(8OMwgX0Sru7t!3{Z?-6IBM;!uXfj;pF_gY%#gh7v9ZV(#Hon-JO< zk8dd~6DOE~Lo(#=5YZzojXe#}6C_b0DTqhA8xvDqv^T{Ge!V|`{yadhr4=h%68BJa zk!u9Cz7650iC?o2=ADF(+rw|)@^51`N!%hx@GgJ9TY{)@=?Sz)hDJw^!yr8hwDAKj zBKV{TqnTIgZ`#qHl*1@I#7qitsIX!xf5%p8HW39L?4Fp8rQdy+9eo5m`HoWh8Ms8n zz=U8_80fDI;4`uM4lm1F*qovP`~Zc|38cK`cXy-FMnmjWyoh!CV+Ppe8fvLbczJj> z5Y!(z-j6VY2p|74okL5{%(HhdC5Hcyv}I_Pwh>*mKA#na3ori>UyeMSb8|4}+Ot21 z>1gn@a5hotVqxq!Nz$|S{d?P^W$T1*96d~3I7Z+_-sCGnn)&lb%)a-qMxq224lKjf zJor%1`KKab8XzF#i5FZZQduy6Ghzy$u+npq@GqNMSX969e(Aw70!pruuHBD;nnA;` zcTCLZ24W@+VuzUPgkIU)4zLLbpJUGy?e?(J ziNjO&<7-L5$2|e!RpDY}G_8mxAZ8TgI>9@#MAB=;=-1b#d^eJo7p6=G*6^joq~f;T z{i0{y{GEvmfL$JT-6y`rx@&KiCBWHWSnS6O8rt7uku6>B;J~QBLqGtVvTqO;x@5zd zIXDc*52B~M2TP1+(d$zX5f;vXnyCX0lF`SwWeXoEwu|RfhR#Im!{Dxp_IgxCs0j~n zDnR9rRNnd=fv(5m;^NrTwI`Mb;j%n4JcU_4W+eM!pEdb^2d9Xc1&m(}Ah~rXzFS6H zWV**T@An9A%UCr;Z!}K^hK6b|7hv%&q7tGKLA@{u3W3KA6N5(ePqrfG{Y9E8``Nv} zMW6)ZIm+@Xvh3RHK^@=}V3EbpB%G5r&lyuNaLFwr6K}i2uu_aOcVkyq*Yo`R8yb9r zhU!$BsS1&!&8gLZX+VnA=n7BHF6oC$O%Uk~m}fFW^rFSA8FldyJ=|>vI(g5gdr`lq zVLcr{W|u|Ifv&`~YgYs;^O0YQUcStI{<^WfodpNDHR+cVEWr#Dtj~C`-B{5YL|aMR zhW=XN35<%FA}LMJ&#R$GzwjmdJj%?pz+fmxeAQ1Nb=cMjhDW4Qz|pbK1)1lHwzIMA z!FaUd+z;6ljn=K$H9mfRe!^sGTOhJI@?+*#409L{tU(ufB9rB{R0QCLfYQ!bz-VK~ zT3?BCu;=`blMqhPKR*h1TPl4jor50?jE=Oqi~Z``Vn5)xtDT&T=xun%e{B@ z_Vz9UJ%}UhF`B_ZjK}2~mxW<)!cq9x&S{GyGX$Yj@Lui*ejYFkYrP#46M!OZ4wMTI zKSwF;K@w#9jWC!Ndo4+H>qOk(@?B-dK7i`s`mX+38|rCuxyxvU69aXKa*iLRxjaO# zY;k$n9P_PzM-7|`sVbiM^bPrx;4KL)G`P}~;TOWt?=aQB@;HH@&>eJzfLyCMrUxe$Y#x%EF2jpa#0;~ewWP5juIy&wB zoSb$JZ?uPphqD(*thAIwuZA$&;7?L;7H(wffA48&hg0JZY1&Aky!U zpu{xQQGlq~C&8Bu2peLeo6d3piQeAjythM`P?)Z&^6bNI%+6gr(>E_wSfLWJIKu&UIZtLy{I| zE=mmVJ)5mN2-JBK%WqWb&Wt>wAAA5dp10x0=a8wxF_2SV-2I>!oQxFEY7nhb2;|sf@$A=F}0DF*z(si-{PeMRB{$m0G9gXKNUikluTw4ombm3X1 zynp{bF|P)Et?_4ap|2e|OVoSk}UQ^;9+!W7m*)m%;So?1#Gq%!M X8oq2|`-wkZgmm(lrfROT>5cyZzr4T` diff --git a/llvm/docs/cycle-3.png b/llvm/docs/cycle-3.png deleted file mode 100644 index 2f1492e0cb60c5ed3cbde2d1310cb427aa00d101..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18776 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 diff --git a/llvm/include/llvm/ADT/GenericCycleImpl.h b/llvm/include/llvm/ADT/GenericCycleImpl.h deleted file mode 100644 index 189e3afbc11a..000000000000 --- a/llvm/include/llvm/ADT/GenericCycleImpl.h +++ /dev/null @@ -1,409 +0,0 @@ -//===- GenericCycleImpl.h -------------------------------------*- C++ -*---===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This template implementation resides in a separate file so that it -// does not get injected into every .cpp file that includes the -// generic header. -// -// DO NOT INCLUDE THIS FILE WHEN MERELY USING CYCLEINFO. -// -// This file should only be included by files that implement a -// specialization of the relevant templates. Currently these are: -// - CycleAnalysis.cpp -// - MachineCycleAnalysis.cpp -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_GENERICCYCLEIMPL_H -#define LLVM_ADT_GENERICCYCLEIMPL_H - -#include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/DepthFirstIterator.h" -#include "llvm/ADT/GenericCycleInfo.h" - -#define DEBUG_TYPE "generic-cycle-impl" - -namespace llvm { - -template -bool GenericCycle::contains(const GenericCycle *C) const { - if (!C) - return false; - - if (Depth > C->Depth) - return false; - while (Depth < C->Depth) - C = C->ParentCycle; - return this == C; -} - -template -void GenericCycle::getExitBlocks( - SmallVectorImpl &TmpStorage) const { - TmpStorage.clear(); - - size_t NumExitBlocks = 0; - for (BlockT *Block : blocks()) { - llvm::append_range(TmpStorage, successors(Block)); - - for (size_t Idx = NumExitBlocks, End = TmpStorage.size(); Idx < End; - ++Idx) { - BlockT *Succ = TmpStorage[Idx]; - if (!contains(Succ)) { - auto ExitEndIt = TmpStorage.begin() + NumExitBlocks; - if (std::find(TmpStorage.begin(), ExitEndIt, Succ) == ExitEndIt) - TmpStorage[NumExitBlocks++] = Succ; - } - } - - TmpStorage.resize(NumExitBlocks); - } -} - -/// \brief Helper class for computing cycle information. -template class GenericCycleInfo::Compute { - GenericCycleInfo &Info; - - struct DFSInfo { - unsigned Start = 0; // DFS start; positive if block is found - unsigned End = 0; // DFS end - - DFSInfo() {} - explicit DFSInfo(unsigned Start) : Start(Start) {} - - /// Whether this node is an ancestor (or equal to) the node \p Other - /// in the DFS tree. - bool isAncestorOf(const DFSInfo &Other) const { - return Start <= Other.Start && Other.End <= End; - } - }; - - DenseMap BlockDFSInfo; - SmallVector BlockPreorder; - - friend struct GraphTraits; - - Compute(const Compute &) = delete; - Compute &operator=(const Compute &) = delete; - -public: - Compute(GenericCycleInfo &Info) : Info(Info) {} - - void run(BlockT *EntryBlock); - - static void updateDepth(CycleT *SubTree); - -private: - void dfs(BlockT *EntryBlock); -}; - -template -auto GenericCycleInfo::getTopLevelParentCycle( - const BlockT *Block) const -> CycleT * { - auto MapIt = BlockMap.find(Block); - if (MapIt == BlockMap.end()) - return nullptr; - - auto *C = MapIt->second; - while (C->ParentCycle) - C = C->ParentCycle; - return C; -} - -template -void GenericCycleInfo::moveToNewParent(CycleT *NewParent, - CycleT *Child) { - auto &CurrentContainer = - Child->ParentCycle ? Child->ParentCycle->Children : TopLevelCycles; - auto Pos = llvm::find_if(CurrentContainer, [=](const auto &Ptr) -> bool { - return Child == Ptr.get(); - }); - assert(Pos != CurrentContainer.end()); - NewParent->Children.push_back(std::move(*Pos)); - *Pos = std::move(CurrentContainer.back()); - CurrentContainer.pop_back(); - Child->ParentCycle = NewParent; -} - -/// \brief Main function of the cycle info computations. -template -void GenericCycleInfo::Compute::run(BlockT *EntryBlock) { - LLVM_DEBUG(errs() << "Entry block: " << Info.Context.print(EntryBlock) - << "\n"); - dfs(EntryBlock); - - SmallVector Worklist; - - for (BlockT *HeaderCandidate : llvm::reverse(BlockPreorder)) { - const DFSInfo CandidateInfo = BlockDFSInfo.lookup(HeaderCandidate); - - for (BlockT *Pred : predecessors(HeaderCandidate)) { - const DFSInfo PredDFSInfo = BlockDFSInfo.lookup(Pred); - if (CandidateInfo.isAncestorOf(PredDFSInfo)) - Worklist.push_back(Pred); - } - if (Worklist.empty()) { - continue; - } - - // Found a cycle with the candidate as its header. - LLVM_DEBUG(errs() << "Found cycle for header: " - << Info.Context.print(HeaderCandidate) << "\n"); - std::unique_ptr NewCycle = std::make_unique(); - NewCycle->appendEntry(HeaderCandidate); - NewCycle->appendBlock(HeaderCandidate); - Info.BlockMap.try_emplace(HeaderCandidate, NewCycle.get()); - - // Helper function to process (non-back-edge) predecessors of a discovered - // block and either add them to the worklist or recognize that the given - // block is an additional cycle entry. - auto ProcessPredecessors = [&](BlockT *Block) { - LLVM_DEBUG(errs() << " block " << Info.Context.print(Block) << ": "); - - bool IsEntry = false; - for (BlockT *Pred : predecessors(Block)) { - const DFSInfo PredDFSInfo = BlockDFSInfo.lookup(Pred); - if (CandidateInfo.isAncestorOf(PredDFSInfo)) { - Worklist.push_back(Pred); - } else { - IsEntry = true; - } - } - if (IsEntry) { - assert(!NewCycle->isEntry(Block)); - LLVM_DEBUG(errs() << "append as entry\n"); - NewCycle->appendEntry(Block); - } else { - LLVM_DEBUG(errs() << "append as child\n"); - } - }; - - do { - BlockT *Block = Worklist.pop_back_val(); - if (Block == HeaderCandidate) - continue; - - // If the block has already been discovered by some cycle - // (possibly by ourself), then the outermost cycle containing it - // should become our child. - if (auto *BlockParent = Info.getTopLevelParentCycle(Block)) { - LLVM_DEBUG(errs() << " block " << Info.Context.print(Block) << ": "); - - if (BlockParent != NewCycle.get()) { - LLVM_DEBUG(errs() - << "discovered child cycle " - << Info.Context.print(BlockParent->getHeader()) << "\n"); - // Make BlockParent the child of NewCycle. - Info.moveToNewParent(NewCycle.get(), BlockParent); - NewCycle->Blocks.insert(NewCycle->Blocks.end(), - BlockParent->block_begin(), - BlockParent->block_end()); - - for (auto *ChildEntry : BlockParent->entries()) - ProcessPredecessors(ChildEntry); - } else { - LLVM_DEBUG(errs() - << "known child cycle " - << Info.Context.print(BlockParent->getHeader()) << "\n"); - } - } else { - Info.BlockMap.try_emplace(Block, NewCycle.get()); - assert(!is_contained(NewCycle->Blocks, Block)); - NewCycle->Blocks.push_back(Block); - ProcessPredecessors(Block); - } - } while (!Worklist.empty()); - - Info.TopLevelCycles.push_back(std::move(NewCycle)); - } - - // Fix top-level cycle links and compute cycle depths. - for (auto *TLC : Info.toplevel_cycles()) { - LLVM_DEBUG(errs() << "top-level cycle: " - << Info.Context.print(TLC->getHeader()) << "\n"); - - TLC->ParentCycle = nullptr; - updateDepth(TLC); - } -} - -/// \brief Recompute depth values of \p SubTree and all descendants. -template -void GenericCycleInfo::Compute::updateDepth(CycleT *SubTree) { - for (CycleT *Cycle : depth_first(SubTree)) - Cycle->Depth = Cycle->ParentCycle ? Cycle->ParentCycle->Depth + 1 : 1; -} - -/// \brief Compute a DFS of basic blocks starting at the function entry. -/// -/// Fills BlockDFSInfo with start/end counters and BlockPreorder. -template -void GenericCycleInfo::Compute::dfs(BlockT *EntryBlock) { - SmallVector DFSTreeStack; - SmallVector TraverseStack; - unsigned Counter = 0; - TraverseStack.emplace_back(EntryBlock); - - do { - BlockT *Block = TraverseStack.back(); - LLVM_DEBUG(errs() << "DFS visiting block: " << Info.Context.print(Block) - << "\n"); - if (!BlockDFSInfo.count(Block)) { - // We're visiting the block for the first time. Open its DFSInfo, add - // successors to the traversal stack, and remember the traversal stack - // depth at which the block was opened, so that we can correctly record - // its end time. - LLVM_DEBUG(errs() << " first encountered at depth " - << TraverseStack.size() << "\n"); - - DFSTreeStack.emplace_back(TraverseStack.size()); - llvm::append_range(TraverseStack, successors(Block)); - - LLVM_ATTRIBUTE_UNUSED - bool Added = BlockDFSInfo.try_emplace(Block, ++Counter).second; - assert(Added); - BlockPreorder.push_back(Block); - LLVM_DEBUG(errs() << " preorder number: " << Counter << "\n"); - } else { - assert(!DFSTreeStack.empty()); - if (DFSTreeStack.back() == TraverseStack.size()) { - LLVM_DEBUG(errs() << " ended at " << Counter << "\n"); - BlockDFSInfo.find(Block)->second.End = Counter; - DFSTreeStack.pop_back(); - } else { - LLVM_DEBUG(errs() << " already done\n"); - } - TraverseStack.pop_back(); - } - } while (!TraverseStack.empty()); - assert(DFSTreeStack.empty()); - - LLVM_DEBUG( - errs() << "Preorder:\n"; - for (int i = 0, e = BlockPreorder.size(); i != e; ++i) { - errs() << " " << Info.Context.print(BlockPreorder[i]) << ": " << i << "\n"; - } - ); -} - -/// \brief Reset the object to its initial state. -template void GenericCycleInfo::clear() { - TopLevelCycles.clear(); - BlockMap.clear(); -} - -/// \brief Compute the cycle info for a function. -template -void GenericCycleInfo::compute(FunctionT &F) { - Compute Compute(*this); - Context.setFunction(F); - - LLVM_DEBUG(errs() << "Computing cycles for function: " << F.getName() - << "\n"); - Compute.run(ContextT::getEntryBlock(F)); - - assert(validateTree()); -} - -/// \brief Find the innermost cycle containing a given block. -/// -/// \returns the innermost cycle containing \p Block or nullptr if -/// it is not contained in any cycle. -template -auto GenericCycleInfo::getCycle(const BlockT *Block) const - -> CycleT * { - auto MapIt = BlockMap.find(Block); - if (MapIt != BlockMap.end()) - return MapIt->second; - return nullptr; -} - -/// \brief Validate the internal consistency of the cycle tree. -/// -/// Note that this does \em not check that cycles are really cycles in the CFG, -/// or that the right set of cycles in the CFG were found. -template -bool GenericCycleInfo::validateTree() const { - DenseSet Blocks; - DenseSet Entries; - - auto reportError = [](const char *File, int Line, const char *Cond) { - errs() << File << ':' << Line - << ": GenericCycleInfo::validateTree: " << Cond << '\n'; - }; -#define check(cond) \ - do { \ - if (!(cond)) { \ - reportError(__FILE__, __LINE__, #cond); \ - return false; \ - } \ - } while (false) - - for (const auto *TLC : toplevel_cycles()) { - for (const CycleT *Cycle : depth_first(TLC)) { - if (Cycle->ParentCycle) - check(is_contained(Cycle->ParentCycle->children(), Cycle)); - - for (BlockT *Block : Cycle->Blocks) { - auto MapIt = BlockMap.find(Block); - check(MapIt != BlockMap.end()); - check(Cycle->contains(MapIt->second)); - check(Blocks.insert(Block).second); // duplicates in block list? - } - Blocks.clear(); - - check(!Cycle->Entries.empty()); - for (BlockT *Entry : Cycle->Entries) { - check(Entries.insert(Entry).second); // duplicate entry? - check(is_contained(Cycle->Blocks, Entry)); - } - Entries.clear(); - - unsigned ChildDepth = 0; - for (const CycleT *Child : Cycle->children()) { - check(Child->Depth > Cycle->Depth); - if (!ChildDepth) { - ChildDepth = Child->Depth; - } else { - check(ChildDepth == Child->Depth); - } - } - } - } - - for (const auto &Entry : BlockMap) { - BlockT *Block = Entry.first; - for (const CycleT *Cycle = Entry.second; Cycle; - Cycle = Cycle->ParentCycle) { - check(is_contained(Cycle->Blocks, Block)); - } - } - -#undef check - - return true; -} - -/// \brief Print the cycle info. -template -void GenericCycleInfo::print(raw_ostream &Out) const { - for (const auto *TLC : toplevel_cycles()) { - for (const CycleT *Cycle : depth_first(TLC)) { - for (unsigned I = 0; I < Cycle->Depth; ++I) - Out << " "; - - Out << Cycle->print(Context) << '\n'; - } - } -} - -} // namespace llvm - -#undef DEBUG_TYPE - -#endif // LLVM_ADT_GENERICCYCLEIMPL_H diff --git a/llvm/include/llvm/ADT/GenericCycleInfo.h b/llvm/include/llvm/ADT/GenericCycleInfo.h deleted file mode 100644 index afe7b685e294..000000000000 --- a/llvm/include/llvm/ADT/GenericCycleInfo.h +++ /dev/null @@ -1,339 +0,0 @@ -//===- GenericCycleInfo.h - Info for Cycles in any IR ------*- C++ -*------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -/// \file -/// \brief Find all cycles in a control-flow graph, including irreducible loops. -/// -/// See docs/CycleTerminology.rst for a formal definition of cycles. -/// -/// Briefly: -/// - A cycle is a generalization of a loop which can represent -/// irreducible control flow. -/// - Cycles identified in a program are implementation defined, -/// depending on the DFS traversal chosen. -/// - Cycles are well-nested, and form a forest with a parent-child -/// relationship. -/// - In any choice of DFS, every natural loop L is represented by a -/// unique cycle C which is a superset of L. -/// - In the absence of irreducible control flow, the cycles are -/// exactly the natural loops in the program. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_GENERICCYCLEINFO_H -#define LLVM_ADT_GENERICCYCLEINFO_H - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/GenericSSAContext.h" -#include "llvm/ADT/GraphTraits.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/iterator.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Printable.h" -#include "llvm/Support/raw_ostream.h" -#include - -namespace llvm { - -template class GenericCycleInfo; - -/// A possibly irreducible generalization of a \ref Loop. -template class GenericCycle { -public: - using BlockT = typename ContextT::BlockT; - using FunctionT = typename ContextT::FunctionT; - template friend class GenericCycleInfo; - -private: - /// The parent cycle. Is null for the root "cycle". Top-level cycles point - /// at the root. - GenericCycle *ParentCycle = nullptr; - - /// The entry block(s) of the cycle. The header is the only entry if - /// this is a loop. Is empty for the root "cycle", to avoid - /// unnecessary memory use. - SmallVector Entries; - - /// Child cycles, if any. - std::vector> Children; - - /// Basic blocks that are contained in the cycle, including entry blocks, - /// and including blocks that are part of a child cycle. - std::vector Blocks; - - /// Depth of the cycle in the tree. The root "cycle" is at depth 0. - /// - /// \note Depths are not necessarily contiguous. However, child loops always - /// have strictly greater depth than their parents, and sibling loops - /// always have the same depth. - unsigned Depth = 0; - - void clear() { - Entries.clear(); - Children.clear(); - Blocks.clear(); - Depth = 0; - ParentCycle = nullptr; - } - - void appendEntry(BlockT *Block) { Entries.push_back(Block); } - void appendBlock(BlockT *Block) { Blocks.push_back(Block); } - - GenericCycle(const GenericCycle &) = delete; - GenericCycle &operator=(const GenericCycle &) = delete; - GenericCycle(GenericCycle &&Rhs) = delete; - GenericCycle &operator=(GenericCycle &&Rhs) = delete; - -public: - GenericCycle() = default; - - /// \brief Whether the cycle is a natural loop. - bool isReducible() const { return Entries.size() == 1; } - - BlockT *getHeader() const { return Entries[0]; } - - /// \brief Return whether \p Block is an entry block of the cycle. - bool isEntry(BlockT *Block) const { return is_contained(Entries, Block); } - - /// \brief Return whether \p Block is contained in the cycle. - bool contains(const BlockT *Block) const { - return is_contained(Blocks, Block); - } - - /// \brief Returns true iff this cycle contains \p C. - /// - /// Note: Non-strict containment check, i.e. returns true if C is the - /// same cycle. - bool contains(const GenericCycle *C) const; - - const GenericCycle *getParentCycle() const { return ParentCycle; } - GenericCycle *getParentCycle() { return ParentCycle; } - unsigned getDepth() const { return Depth; } - - /// Return all of the successor blocks of this cycle. - /// - /// These are the blocks _outside of the current cycle_ which are - /// branched to. - void getExitBlocks(SmallVectorImpl &TmpStorage) const; - - /// Iteration over child cycles. - //@{ - using const_child_iterator_base = - typename std::vector>::const_iterator; - struct const_child_iterator - : iterator_adaptor_base { - using Base = - iterator_adaptor_base; - - const_child_iterator() = default; - explicit const_child_iterator(const_child_iterator_base I) : Base(I) {} - - const const_child_iterator_base &wrapped() { return Base::wrapped(); } - GenericCycle *operator*() const { return Base::I->get(); } - }; - - const_child_iterator child_begin() const { - return const_child_iterator{Children.begin()}; - } - const_child_iterator child_end() const { - return const_child_iterator{Children.end()}; - } - size_t getNumChildren() const { return Children.size(); } - iterator_range children() const { - return llvm::make_range(const_child_iterator{Children.begin()}, - const_child_iterator{Children.end()}); - } - //@} - - /// Iteration over blocks in the cycle (including entry blocks). - //@{ - using const_block_iterator = typename std::vector::const_iterator; - - const_block_iterator block_begin() const { - return const_block_iterator{Blocks.begin()}; - } - const_block_iterator block_end() const { - return const_block_iterator{Blocks.end()}; - } - size_t getNumBlocks() const { return Blocks.size(); } - iterator_range blocks() const { - return llvm::make_range(block_begin(), block_end()); - } - //@} - - /// Iteration over entry blocks. - //@{ - using const_entry_iterator = - typename SmallVectorImpl::const_iterator; - - size_t getNumEntries() const { return Entries.size(); } - iterator_range entries() const { - return llvm::make_range(Entries.begin(), Entries.end()); - } - - Printable printEntries(const ContextT &Ctx) const { - return Printable([this, &Ctx](raw_ostream &Out) { - bool First = true; - for (auto *Entry : Entries) { - if (!First) - Out << ' '; - First = false; - Out << Ctx.print(Entry); - } - }); - } - - Printable print(const ContextT &Ctx) const { - return Printable([this, &Ctx](raw_ostream &Out) { - Out << "depth=" << Depth << ": entries(" << printEntries(Ctx) << ')'; - - for (auto *Block : Blocks) { - if (isEntry(Block)) - continue; - - Out << ' ' << Ctx.print(Block); - } - }); - } -}; - -/// \brief Cycle information for a function. -template class GenericCycleInfo { -public: - using BlockT = typename ContextT::BlockT; - using CycleT = GenericCycle; - using FunctionT = typename ContextT::FunctionT; - template friend class GenericCycle; - -private: - ContextT Context; - - /// Map basic blocks to their inner-most containing loop. - DenseMap BlockMap; - - /// Outermost cycles discovered by any DFS. - /// - /// Note: The implementation treats the nullptr as the parent of - /// every top-level cycle. See \ref contains for an example. - std::vector> TopLevelCycles; - -public: - GenericCycleInfo() = default; - GenericCycleInfo(GenericCycleInfo &&) = default; - GenericCycleInfo &operator=(GenericCycleInfo &&) = default; - - void clear(); - void compute(FunctionT &F); - - FunctionT *getFunction() const { return Context.getFunction(); } - const ContextT &getSSAContext() const { return Context; } - - CycleT *getCycle(const BlockT *Block) const; - CycleT *getTopLevelParentCycle(const BlockT *Block) const; - - /// Move \p Child to \p NewParent by manipulating Children vectors. - /// - /// Note: This is an incomplete operation that does not update the - /// list of blocks in the new parent or the depth of the subtree. - void moveToNewParent(CycleT *NewParent, CycleT *Child); - - /// Methods for debug and self-test. - //@{ - bool validateTree() const; - void print(raw_ostream &Out) const; - void dump() const { print(dbgs()); } - //@} - - /// Iteration over top-level cycles. - //@{ - using const_toplevel_iterator_base = - typename std::vector>::const_iterator; - struct const_toplevel_iterator - : iterator_adaptor_base { - using Base = iterator_adaptor_base; - - const_toplevel_iterator() = default; - explicit const_toplevel_iterator(const_toplevel_iterator_base I) - : Base(I) {} - - const const_toplevel_iterator_base &wrapped() { return Base::wrapped(); } - CycleT *operator*() const { return Base::I->get(); } - }; - - const_toplevel_iterator toplevel_begin() const { - return const_toplevel_iterator{TopLevelCycles.begin()}; - } - const_toplevel_iterator toplevel_end() const { - return const_toplevel_iterator{TopLevelCycles.end()}; - } - - iterator_range toplevel_cycles() const { - return llvm::make_range(const_toplevel_iterator{TopLevelCycles.begin()}, - const_toplevel_iterator{TopLevelCycles.end()}); - } - //@} - -private: - // Helper classes used by the cycle info computation. - class ContractedDomSubTree; - class Compute; - - friend struct GraphTraits; - friend struct DenseMapInfo; -}; - -/// \brief GraphTraits for iterating over a sub-tree of the CycleT tree. -template struct CycleGraphTraits { - using NodeRef = CycleRefT; - - using nodes_iterator = ChildIteratorT; - using ChildIteratorType = nodes_iterator; - - static NodeRef getEntryNode(NodeRef Graph) { return Graph; } - - static ChildIteratorType child_begin(NodeRef Ref) { - return Ref->child_begin(); - } - static ChildIteratorType child_end(NodeRef Ref) { return Ref->child_end(); } - - // Not implemented: - // static nodes_iterator nodes_begin(GraphType *G) - // static nodes_iterator nodes_end (GraphType *G) - // nodes_iterator/begin/end - Allow iteration over all nodes in the graph - - // typedef EdgeRef - Type of Edge token in the graph, which should - // be cheap to copy. - // typedef ChildEdgeIteratorType - Type used to iterate over children edges in - // graph, dereference to a EdgeRef. - - // static ChildEdgeIteratorType child_edge_begin(NodeRef) - // static ChildEdgeIteratorType child_edge_end(NodeRef) - // Return iterators that point to the beginning and ending of the - // edge list for the given callgraph node. - // - // static NodeRef edge_dest(EdgeRef) - // Return the destination node of an edge. - // static unsigned size (GraphType *G) - // Return total number of nodes in the graph -}; - -template -struct GraphTraits *> - : CycleGraphTraits *, - typename GenericCycle::const_child_iterator> {}; -template -struct GraphTraits *> - : CycleGraphTraits *, - typename GenericCycle::const_child_iterator> {}; - -} // namespace llvm - -#endif // LLVM_ADT_GENERICCYCLEINFO_H diff --git a/llvm/include/llvm/ADT/GenericSSAContext.h b/llvm/include/llvm/ADT/GenericSSAContext.h deleted file mode 100644 index 409222547d5c..000000000000 --- a/llvm/include/llvm/ADT/GenericSSAContext.h +++ /dev/null @@ -1,74 +0,0 @@ -//===- GenericSSAContext.h --------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -/// \file -/// -/// This file defines the little GenericSSAContext template class -/// that can be used to implement IR analyses as templates. -/// Specializing these templates allows the analyses to be used over -/// both LLVM IR and Machine IR. -/// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_GENERICSSACONTEXT_H -#define LLVM_ADT_GENERICSSACONTEXT_H - -#include "llvm/Support/Printable.h" - -namespace llvm { - -template class GenericSSAContext { -public: - // Specializations should provide the following types that are similar to how - // LLVM IR is structured: - - // The smallest unit of the IR is a ValueT. The SSA context uses a ValueRefT, - // which is a pointer to a ValueT, since Machine IR does not have the - // equivalent of a ValueT. - // - // using ValueRefT = ... - - // An InstT is a subclass of ValueT that itself defines one or more ValueT - // objects. - // - // using InstT = ... must be a subclass of Value - - // A BlockT is a sequence of InstT, and forms a node of the CFG. It - // has global methods predecessors() and successors() that return - // the list of incoming CFG edges and outgoing CFG edges - // respectively. - // - // using BlockT = ... - - // A FunctionT represents a CFG along with arguments and return values. It is - // the smallest complete unit of code in a Module. - // - // The compiler produces an error here if this class is implicitly - // specialized due to an instantiation. An explicit specialization - // of this template needs to be added before the instantiation point - // indicated by the compiler. - using FunctionT = typename _FunctionT::invalidTemplateInstanceError; - - // Every FunctionT has a unique BlockT marked as its entry. - // - // static BlockT* getEntryBlock(FunctionT &F); - - // Initialize the SSA context with information about the FunctionT being - // processed. - // - // void setFunction(FunctionT &function); - // FunctionT* getFunction() const; - - // Methods to print various objects. - // - // Printable print(BlockT *block) const; - // Printable print(InstructionT *inst) const; - // Printable print(ValueRefT value) const; -}; -} // namespace llvm - -#endif // LLVM_ADT_GENERICSSACONTEXT_H diff --git a/llvm/include/llvm/Analysis/CycleAnalysis.h b/llvm/include/llvm/Analysis/CycleAnalysis.h deleted file mode 100644 index e16b908d6a10..000000000000 --- a/llvm/include/llvm/Analysis/CycleAnalysis.h +++ /dev/null @@ -1,77 +0,0 @@ -//===- CycleAnalysis.h - Cycle Info for LLVM IR -----------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -/// \file -/// -/// This file declares an analysis pass that computes CycleInfo for -/// LLVM IR, specialized from GenericCycleInfo. -/// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ANALYSIS_CYCLEANALYSIS_H -#define LLVM_ANALYSIS_CYCLEANALYSIS_H - -#include "llvm/ADT/GenericCycleInfo.h" -#include "llvm/IR/PassManager.h" -#include "llvm/IR/SSAContext.h" - -namespace llvm { -extern template class GenericCycleInfo; -extern template class GenericCycle; - -using CycleInfo = GenericCycleInfo; -using Cycle = CycleInfo::CycleT; - -/// Analysis pass which computes a \ref CycleInfo. -class CycleAnalysis : public AnalysisInfoMixin { - friend AnalysisInfoMixin; - static AnalysisKey Key; - -public: - /// Provide the result typedef for this analysis pass. - using Result = CycleInfo; - - /// Run the analysis pass over a function and produce a dominator tree. - CycleInfo run(Function &F, FunctionAnalysisManager &); - - // TODO: verify analysis? -}; - -/// Printer pass for the \c DominatorTree. -class CycleInfoPrinterPass : public PassInfoMixin { - raw_ostream &OS; - -public: - explicit CycleInfoPrinterPass(raw_ostream &OS); - - PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); -}; - -/// Legacy analysis pass which computes a \ref CycleInfo. -class CycleInfoWrapperPass : public FunctionPass { - Function *F = nullptr; - CycleInfo CI; - -public: - static char ID; - - CycleInfoWrapperPass(); - - CycleInfo &getCycleInfo() { return CI; } - const CycleInfo &getCycleInfo() const { return CI; } - - bool runOnFunction(Function &F) override; - void getAnalysisUsage(AnalysisUsage &AU) const override; - void releaseMemory() override; - void print(raw_ostream &OS, const Module *M = nullptr) const override; - - // TODO: verify analysis? -}; - -} // end namespace llvm - -#endif // LLVM_ANALYSIS_CYCLEANALYSIS_H diff --git a/llvm/include/llvm/CodeGen/MachineCycleAnalysis.h b/llvm/include/llvm/CodeGen/MachineCycleAnalysis.h deleted file mode 100644 index c9f30dcbe48d..000000000000 --- a/llvm/include/llvm/CodeGen/MachineCycleAnalysis.h +++ /dev/null @@ -1,63 +0,0 @@ -//===- MachineCycleAnalysis.h - Cycle Info for Machine IR -------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the MachineCycleInfo class, which is a thin wrapper over -// the Machine IR instance of GenericCycleInfo. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_MACHINECYCLEANALYSIS_H -#define LLVM_CODEGEN_MACHINECYCLEANALYSIS_H - -#include "llvm/ADT/GenericCycleInfo.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineSSAContext.h" - -namespace llvm { - -extern template class GenericCycleInfo; -extern template class GenericCycle; - -using MachineCycleInfo = GenericCycleInfo; -using MachineCycle = MachineCycleInfo::CycleT; - -/// Legacy analysis pass which computes a \ref MachineCycleInfo. -class MachineCycleInfoWrapperPass : public MachineFunctionPass { - MachineFunction *F = nullptr; - MachineCycleInfo CI; - -public: - static char ID; - - MachineCycleInfoWrapperPass(); - - MachineCycleInfo &getCycleInfo() { return CI; } - const MachineCycleInfo &getCycleInfo() const { return CI; } - - bool runOnMachineFunction(MachineFunction &F) override; - void getAnalysisUsage(AnalysisUsage &AU) const override; - void releaseMemory() override; - void print(raw_ostream &OS, const Module *M = nullptr) const override; - - // TODO: verify analysis -}; - -/// Legacy analysis pass which computes a \ref MachineCycleInfo. -class MachineCycleInfoPrinterPass : public MachineFunctionPass { -public: - static char ID; - - MachineCycleInfoPrinterPass(); - - bool runOnMachineFunction(MachineFunction &F) override; - void getAnalysisUsage(AnalysisUsage &AU) const override; -}; - -} // end namespace llvm - -#endif // LLVM_CODEGEN_MACHINECYCLEANALYSIS_H diff --git a/llvm/include/llvm/CodeGen/MachinePassRegistry.def b/llvm/include/llvm/CodeGen/MachinePassRegistry.def index e6763899a083..d79303c771d6 100644 --- a/llvm/include/llvm/CodeGen/MachinePassRegistry.def +++ b/llvm/include/llvm/CodeGen/MachinePassRegistry.def @@ -197,6 +197,4 @@ DUMMY_MACHINE_FUNCTION_PASS("regbankselect", RegBankSelectPass, ()) DUMMY_MACHINE_FUNCTION_PASS("instruction-select", InstructionSelectPass, ()) DUMMY_MACHINE_FUNCTION_PASS("reset-machine-function", ResetMachineFunctionPass, ()) DUMMY_MACHINE_FUNCTION_PASS("machineverifier", MachineVerifierPass, ()) -DUMMY_MACHINE_FUNCTION_PASS("machine-cycles", MachineCycleInfoWrapperPass, ()) -DUMMY_MACHINE_FUNCTION_PASS("print-machine-cycles", MachineCycleInfoPrinterPass, ()) #undef DUMMY_MACHINE_FUNCTION_PASS diff --git a/llvm/include/llvm/CodeGen/MachineSSAContext.h b/llvm/include/llvm/CodeGen/MachineSSAContext.h deleted file mode 100644 index 6dbf321bdeaa..000000000000 --- a/llvm/include/llvm/CodeGen/MachineSSAContext.h +++ /dev/null @@ -1,58 +0,0 @@ -//===- MachineSSAContext.h --------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -/// \file -/// -/// This file declares a specialization of the GenericSSAContext -/// template class for Machine IR. -/// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_MACHINESSACONTEXT_H -#define LLVM_CODEGEN_MACHINESSACONTEXT_H - -#include "llvm/ADT/GenericSSAContext.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/Support/Printable.h" - -#include - -namespace llvm { -class MachineInstr; -class MachineBasicBlock; -class MachineFunction; -class Register; -template class DominatorTreeBase; - -inline auto successors(MachineBasicBlock *BB) { return BB->successors(); } -inline auto predecessors(MachineBasicBlock *BB) { return BB->predecessors(); } - -template <> class GenericSSAContext { - const MachineRegisterInfo *RegInfo = nullptr; - MachineFunction *MF; - -public: - using BlockT = MachineBasicBlock; - using FunctionT = MachineFunction; - using InstructionT = MachineInstr; - using ValueRefT = Register; - using DominatorTreeT = DominatorTreeBase; - - static MachineBasicBlock *getEntryBlock(MachineFunction &F); - - void setFunction(MachineFunction &Fn); - MachineFunction *getFunction() const { return MF; } - - Printable print(MachineBasicBlock *Block) const; - Printable print(MachineInstr *Inst) const; - Printable print(Register Value) const; -}; - -using MachineSSAContext = GenericSSAContext; -} // namespace llvm - -#endif // LLVM_CODEGEN_MACHINESSACONTEXT_H diff --git a/llvm/include/llvm/IR/SSAContext.h b/llvm/include/llvm/IR/SSAContext.h deleted file mode 100644 index 9d9290a2c1d7..000000000000 --- a/llvm/include/llvm/IR/SSAContext.h +++ /dev/null @@ -1,56 +0,0 @@ -//===- SSAContext.h ---------------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -/// \file -/// -/// This file declares a specialization of the GenericSSAContext -/// class template for LLVM IR. -/// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_IR_SSACONTEXT_H -#define LLVM_IR_SSACONTEXT_H - -#include "llvm/ADT/GenericSSAContext.h" -#include "llvm/IR/ModuleSlotTracker.h" -#include "llvm/Support/Printable.h" - -#include - -namespace llvm { -class BasicBlock; -class Function; -class Instruction; -class Value; -template class SmallVectorImpl; -template class DominatorTreeBase; - -template <> class GenericSSAContext { - Function *F; - -public: - using BlockT = BasicBlock; - using FunctionT = Function; - using InstructionT = Instruction; - using ValueRefT = Value *; - using DominatorTreeT = DominatorTreeBase; - - static BasicBlock *getEntryBlock(Function &F); - - void setFunction(Function &Fn); - Function *getFunction() const { return F; } - - Printable print(BasicBlock *Block) const; - Printable print(Instruction *Inst) const; - Printable print(Value *Value) const; -}; - -using SSAContext = GenericSSAContext; - -} // namespace llvm - -#endif // LLVM_IR_SSACONTEXT_H diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index 29c31db2c8af..845d7dcdebd2 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -122,7 +122,6 @@ void initializeControlHeightReductionLegacyPassPass(PassRegistry&); void initializeCorrelatedValuePropagationPass(PassRegistry&); void initializeCostModelAnalysisPass(PassRegistry&); void initializeCrossDSOCFIPass(PassRegistry&); -void initializeCycleInfoWrapperPassPass(PassRegistry &); void initializeDAEPass(PassRegistry&); void initializeDAHPass(PassRegistry&); void initializeDCELegacyPassPass(PassRegistry&); @@ -292,8 +291,6 @@ void initializeMachineBranchProbabilityInfoPass(PassRegistry&); void initializeMachineCSEPass(PassRegistry&); void initializeMachineCombinerPass(PassRegistry&); void initializeMachineCopyPropagationPass(PassRegistry&); -void initializeMachineCycleInfoPrinterPassPass(PassRegistry &); -void initializeMachineCycleInfoWrapperPassPass(PassRegistry &); void initializeMachineDominanceFrontierPass(PassRegistry&); void initializeMachineDominatorTreePass(PassRegistry&); void initializeMachineFunctionPrinterPassPass(PassRegistry&); diff --git a/llvm/lib/Analysis/Analysis.cpp b/llvm/lib/Analysis/Analysis.cpp index 177f38af13d8..db5167061509 100644 --- a/llvm/lib/Analysis/Analysis.cpp +++ b/llvm/lib/Analysis/Analysis.cpp @@ -35,7 +35,6 @@ void llvm::initializeAnalysis(PassRegistry &Registry) { initializeCFGOnlyPrinterLegacyPassPass(Registry); initializeCFLAndersAAWrapperPassPass(Registry); initializeCFLSteensAAWrapperPassPass(Registry); - initializeCycleInfoWrapperPassPass(Registry); initializeDependenceAnalysisWrapperPassPass(Registry); initializeDelinearizationPass(Registry); initializeDemandedBitsWrapperPassPass(Registry); diff --git a/llvm/lib/Analysis/CMakeLists.txt b/llvm/lib/Analysis/CMakeLists.txt index 3d880597ae01..9da07cb1c485 100644 --- a/llvm/lib/Analysis/CMakeLists.txt +++ b/llvm/lib/Analysis/CMakeLists.txt @@ -50,7 +50,6 @@ add_llvm_component_library(LLVMAnalysis CostModel.cpp CodeMetrics.cpp ConstantFolding.cpp - CycleAnalysis.cpp DDG.cpp DDGPrinter.cpp ConstraintSystem.cpp diff --git a/llvm/lib/Analysis/CycleAnalysis.cpp b/llvm/lib/Analysis/CycleAnalysis.cpp deleted file mode 100644 index 09c7ee67e05c..000000000000 --- a/llvm/lib/Analysis/CycleAnalysis.cpp +++ /dev/null @@ -1,77 +0,0 @@ -//===- CycleAnalysis.cpp - Compute CycleInfo for LLVM IR ------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm/Analysis/CycleAnalysis.h" -#include "llvm/ADT/GenericCycleImpl.h" -#include "llvm/IR/CFG.h" -#include "llvm/InitializePasses.h" - -using namespace llvm; - -template class llvm::GenericCycleInfo; -template class llvm::GenericCycle; - -CycleInfo CycleAnalysis::run(Function &F, FunctionAnalysisManager &) { - CycleInfo CI; - CI.compute(F); - return CI; -} - -AnalysisKey CycleAnalysis::Key; - -CycleInfoPrinterPass::CycleInfoPrinterPass(raw_ostream &OS) : OS(OS) {} - -PreservedAnalyses CycleInfoPrinterPass::run(Function &F, - FunctionAnalysisManager &AM) { - OS << "CycleInfo for function: " << F.getName() << "\n"; - AM.getResult(F).print(OS); - - return PreservedAnalyses::all(); -} - -//===----------------------------------------------------------------------===// -// CycleInfoWrapperPass Implementation -//===----------------------------------------------------------------------===// -// -// The implementation details of the wrapper pass that holds a CycleInfo -// suitable for use with the legacy pass manager. -// -//===----------------------------------------------------------------------===// - -char CycleInfoWrapperPass::ID = 0; - -CycleInfoWrapperPass::CycleInfoWrapperPass() : FunctionPass(ID) { - initializeCycleInfoWrapperPassPass(*PassRegistry::getPassRegistry()); -} - -INITIALIZE_PASS_BEGIN(CycleInfoWrapperPass, "cycles", "Cycle Info Analysis", - true, true) -INITIALIZE_PASS_END(CycleInfoWrapperPass, "cycles", "Cycle Info Analysis", true, - true) - -void CycleInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); -} - -bool CycleInfoWrapperPass::runOnFunction(Function &Func) { - CI.clear(); - - F = &Func; - CI.compute(Func); - return false; -} - -void CycleInfoWrapperPass::print(raw_ostream &OS, const Module *) const { - OS << "CycleInfo for function: " << F->getName() << "\n"; - CI.print(OS); -} - -void CycleInfoWrapperPass::releaseMemory() { - CI.clear(); - F = nullptr; -} diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt index 9d26a3f31646..abe2d2954568 100644 --- a/llvm/lib/CodeGen/CMakeLists.txt +++ b/llvm/lib/CodeGen/CMakeLists.txt @@ -77,7 +77,6 @@ add_llvm_component_library(LLVMCodeGen MachineCopyPropagation.cpp MachineCSE.cpp MachineCheckDebugify.cpp - MachineCycleAnalysis.cpp MachineDebugify.cpp MachineDominanceFrontier.cpp MachineDominators.cpp @@ -105,7 +104,6 @@ add_llvm_component_library(LLVMCodeGen MachineScheduler.cpp MachineSink.cpp MachineSizeOpts.cpp - MachineSSAContext.cpp MachineSSAUpdater.cpp MachineStripDebug.cpp MachineTraceMetrics.cpp diff --git a/llvm/lib/CodeGen/CodeGen.cpp b/llvm/lib/CodeGen/CodeGen.cpp index 7c236a9785d8..bbdd8aab502e 100644 --- a/llvm/lib/CodeGen/CodeGen.cpp +++ b/llvm/lib/CodeGen/CodeGen.cpp @@ -68,8 +68,6 @@ void llvm::initializeCodeGen(PassRegistry &Registry) { initializeMachineCSEPass(Registry); initializeMachineCombinerPass(Registry); initializeMachineCopyPropagationPass(Registry); - initializeMachineCycleInfoPrinterPassPass(Registry); - initializeMachineCycleInfoWrapperPassPass(Registry); initializeMachineDominatorTreePass(Registry); initializeMachineFunctionPrinterPassPass(Registry); initializeMachineLICMPass(Registry); diff --git a/llvm/lib/CodeGen/MachineCycleAnalysis.cpp b/llvm/lib/CodeGen/MachineCycleAnalysis.cpp deleted file mode 100644 index 2a1b456724e6..000000000000 --- a/llvm/lib/CodeGen/MachineCycleAnalysis.cpp +++ /dev/null @@ -1,87 +0,0 @@ -//===- MachineCycleAnalysis.cpp - Compute CycleInfo for Machine IR --------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm/CodeGen/MachineCycleAnalysis.h" -#include "llvm/ADT/GenericCycleImpl.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineSSAContext.h" -#include "llvm/InitializePasses.h" - -using namespace llvm; - -template class llvm::GenericCycleInfo; -template class llvm::GenericCycle; - -//===----------------------------------------------------------------------===// -// MachineCycleInfoWrapperPass Implementation -//===----------------------------------------------------------------------===// -// -// The implementation details of the wrapper pass that holds a MachineCycleInfo -// suitable for use with the legacy pass manager. -// -//===----------------------------------------------------------------------===// - -char MachineCycleInfoWrapperPass::ID = 0; - -MachineCycleInfoWrapperPass::MachineCycleInfoWrapperPass() - : MachineFunctionPass(ID) { - initializeMachineCycleInfoWrapperPassPass(*PassRegistry::getPassRegistry()); -} - -INITIALIZE_PASS_BEGIN(MachineCycleInfoWrapperPass, "machine-cycles", - "Machine Cycle Info Analysis", true, true) -INITIALIZE_PASS_END(MachineCycleInfoWrapperPass, "machine-cycles", - "Machine Cycle Info Analysis", true, true) - -void MachineCycleInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - MachineFunctionPass::getAnalysisUsage(AU); -} - -bool MachineCycleInfoWrapperPass::runOnMachineFunction(MachineFunction &Func) { - CI.clear(); - - F = &Func; - CI.compute(Func); - return false; -} - -void MachineCycleInfoWrapperPass::print(raw_ostream &OS, const Module *) const { - OS << "MachineCycleInfo for function: " << F->getName() << "\n"; - CI.print(OS); -} - -void MachineCycleInfoWrapperPass::releaseMemory() { - CI.clear(); - F = nullptr; -} - -char MachineCycleInfoPrinterPass::ID = 0; - -MachineCycleInfoPrinterPass::MachineCycleInfoPrinterPass() - : MachineFunctionPass(ID) { - initializeMachineCycleInfoPrinterPassPass(*PassRegistry::getPassRegistry()); -} - -INITIALIZE_PASS_BEGIN(MachineCycleInfoPrinterPass, "print-machine-cycles", - "Print Machine Cycle Info Analysis", true, true) -INITIALIZE_PASS_DEPENDENCY(MachineCycleInfoWrapperPass) -INITIALIZE_PASS_END(MachineCycleInfoPrinterPass, "print-machine-cycles", - "Print Machine Cycle Info Analysis", true, true) - -void MachineCycleInfoPrinterPass::getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - AU.addRequired(); - MachineFunctionPass::getAnalysisUsage(AU); -} - -bool MachineCycleInfoPrinterPass::runOnMachineFunction(MachineFunction &F) { - auto &CI = getAnalysis(); - CI.print(errs()); - return false; -} diff --git a/llvm/lib/CodeGen/MachineSSAContext.cpp b/llvm/lib/CodeGen/MachineSSAContext.cpp deleted file mode 100644 index 8db893535daf..000000000000 --- a/llvm/lib/CodeGen/MachineSSAContext.cpp +++ /dev/null @@ -1,52 +0,0 @@ -//===- MachineSSAContext.cpp ------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -/// \file -/// -/// This file defines a specialization of the GenericSSAContext -/// template class for Machine IR. -/// -//===----------------------------------------------------------------------===// - -#include "llvm/CodeGen/MachineSSAContext.h" -#include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/Support/raw_ostream.h" - -using namespace llvm; - -MachineBasicBlock *MachineSSAContext::getEntryBlock(MachineFunction &F) { - return &F.front(); -} - -void MachineSSAContext::setFunction(MachineFunction &Fn) { - MF = &Fn; - RegInfo = &MF->getRegInfo(); -} - -Printable MachineSSAContext::print(MachineBasicBlock *Block) const { - return Printable([Block](raw_ostream &Out) { Block->printName(Out); }); -} - -Printable MachineSSAContext::print(MachineInstr *I) const { - return Printable([I](raw_ostream &Out) { I->print(Out); }); -} - -Printable MachineSSAContext::print(Register Value) const { - auto *MRI = RegInfo; - return Printable([MRI, Value](raw_ostream &Out) { - Out << printReg(Value, MRI->getTargetRegisterInfo(), 0, MRI); - - if (Value) { - // Try to print the definition. - if (auto *Instr = MRI->getUniqueVRegDef(Value)) { - Out << ": "; - Instr->print(Out); - } - } - }); -} diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt index 2c09e57c3f97..7f6e698b10f9 100644 --- a/llvm/lib/IR/CMakeLists.txt +++ b/llvm/lib/IR/CMakeLists.txt @@ -27,7 +27,6 @@ add_llvm_component_library(LLVMCore Globals.cpp IRBuilder.cpp IRPrintingPasses.cpp - SSAContext.cpp InlineAsm.cpp Instruction.cpp Instructions.cpp diff --git a/llvm/lib/IR/SSAContext.cpp b/llvm/lib/IR/SSAContext.cpp deleted file mode 100644 index a96e39f32882..000000000000 --- a/llvm/lib/IR/SSAContext.cpp +++ /dev/null @@ -1,47 +0,0 @@ -//===- SSAContext.cpp -------------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -/// \file -/// -/// This file defines a specialization of the GenericSSAContext -/// template class for LLVM IR. -/// -//===----------------------------------------------------------------------===// - -#include "llvm/IR/SSAContext.h" -#include "llvm/IR/Argument.h" -#include "llvm/IR/BasicBlock.h" -#include "llvm/IR/Function.h" -#include "llvm/IR/Instruction.h" -#include "llvm/Support/raw_ostream.h" - -using namespace llvm; - -BasicBlock *SSAContext::getEntryBlock(Function &F) { - return &F.getEntryBlock(); -} - -void SSAContext::setFunction(Function &Fn) { F = &Fn; } - -Printable SSAContext::print(Value *V) const { - return Printable([V](raw_ostream &Out) { V->print(Out); }); -} - -Printable SSAContext::print(Instruction *Inst) const { - return print(cast(Inst)); -} - -Printable SSAContext::print(BasicBlock *BB) const { - if (BB->hasName()) - return Printable([BB](raw_ostream &Out) { Out << BB->getName(); }); - - return Printable([BB](raw_ostream &Out) { - ModuleSlotTracker MST{BB->getParent()->getParent(), false}; - MST.incorporateFunction(*BB->getParent()); - Out << MST.getLocalSlot(BB); - }); -} diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index f897faa2c22c..561a881bab0c 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -28,7 +28,6 @@ #include "llvm/Analysis/CGSCCPassManager.h" #include "llvm/Analysis/CallGraph.h" #include "llvm/Analysis/CostModel.h" -#include "llvm/Analysis/CycleAnalysis.h" #include "llvm/Analysis/DDG.h" #include "llvm/Analysis/DDGPrinter.h" #include "llvm/Analysis/Delinearization.h" diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index c98ede7a44e5..c2032b5b8276 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -185,7 +185,6 @@ FUNCTION_ANALYSIS("aa", AAManager()) FUNCTION_ANALYSIS("assumptions", AssumptionAnalysis()) FUNCTION_ANALYSIS("block-freq", BlockFrequencyAnalysis()) FUNCTION_ANALYSIS("branch-prob", BranchProbabilityAnalysis()) -FUNCTION_ANALYSIS("cycles", CycleAnalysis()) FUNCTION_ANALYSIS("domtree", DominatorTreeAnalysis()) FUNCTION_ANALYSIS("postdomtree", PostDominatorTreeAnalysis()) FUNCTION_ANALYSIS("demanded-bits", DemandedBitsAnalysis()) @@ -304,7 +303,6 @@ FUNCTION_PASS("print", AssumptionPrinterPass(dbgs())) FUNCTION_PASS("print", BlockFrequencyPrinterPass(dbgs())) FUNCTION_PASS("print", BranchProbabilityPrinterPass(dbgs())) FUNCTION_PASS("print", CostModelPrinterPass(dbgs())) -FUNCTION_PASS("print", CycleInfoPrinterPass(dbgs())) FUNCTION_PASS("print", DependenceAnalysisPrinterPass(dbgs())) FUNCTION_PASS("print", DivergenceAnalysisPrinterPass(dbgs())) FUNCTION_PASS("print", DominatorTreePrinterPass(dbgs())) diff --git a/llvm/test/Analysis/CycleInfo/basic.ll b/llvm/test/Analysis/CycleInfo/basic.ll deleted file mode 100644 index dd6b4fa6ad25..000000000000 --- a/llvm/test/Analysis/CycleInfo/basic.ll +++ /dev/null @@ -1,302 +0,0 @@ -; RUN: opt < %s -cycles -analyze -enable-new-pm=0 | FileCheck %s -check-prefix=CHECK -; RUN: opt < %s -disable-output -passes='print' 2>&1 | FileCheck %s -check-prefix=CHECK - -define void @empty() { -; CHECK-LABEL: CycleInfo for function: empty -; CHECK-NOT: depth - - ret void -} - -define void @simple() { -; CHECK-LABEL: CycleInfo for function: simple -; CHECK: depth=1: entries(loop) -entry: - br label %loop - -loop: - br i1 undef, label %loop, label %exit - -exit: - ret void -} - -define void @two_latches() { -; CHECK-LABEL: CycleInfo for function: two_latches -; CHECK: depth=1: entries(loop) loop_next -entry: - br label %loop - -loop: - br i1 undef, label %loop, label %loop_next - -loop_next: - br i1 undef, label %exit, label %loop - -exit: - ret void -} - -define void @nested_simple() { -; CHECK-LABEL: CycleInfo for function: nested_simple -; CHECK: depth=1: entries(outer_header) outer_latch inner -; CHECK: depth=2: entries(inner) -entry: - br label %outer_header - -outer_header: - br label %inner - -inner: - br i1 undef, label %inner, label %outer_latch - -outer_latch: - br i1 undef, label %outer_header, label %exit - -exit: - ret void -} - -define void @nested_outer_latch_in_inner_loop() { -; CHECK-LABEL: CycleInfo for function: nested_outer_latch_in_inner_loop -; CHECK: depth=1: entries(outer_header) inner_header inner_latch -; CHECK: depth=2: entries(inner_header) inner_latch -entry: - br label %outer_header - -outer_header: - br label %inner_header - -inner_header: - br i1 undef, label %inner_latch, label %outer_header - -inner_latch: - br i1 undef, label %exit, label %inner_header - -exit: - ret void -} - -define void @sibling_loops() { -; CHECK-LABEL: CycleInfo for function: sibling_loops -; CHECK-DAG: depth=1: entries(left) -; CHECK-DAG: depth=1: entries(right) -entry: - br i1 undef, label %left, label %right - -left: - br i1 undef, label %left, label %exit - -right: - br i1 undef, label %right, label %exit - -exit: - ret void -} - -define void @serial_loops() { -; CHECK-LABEL: CycleInfo for function: serial_loops -; CHECK-DAG: depth=1: entries(second) -; CHECK-DAG: depth=1: entries(first) -entry: - br label %first - -first: - br i1 undef, label %first, label %second - -second: - br i1 undef, label %second, label %exit - -exit: - ret void -} - -define void @nested_sibling_loops() { -; CHECK-LABEL: CycleInfo for function: nested_sibling_loops -; CHECK: depth=1: entries(outer_header) left right -; CHECK-DAG: depth=2: entries(right) -; CHECK-DAG: depth=2: entries(left) -entry: - br label %outer_header - -outer_header: - br i1 undef, label %left, label %right - -left: - switch i32 undef, label %exit [ i32 0, label %left - i32 1, label %outer_header ] - -right: - switch i32 undef, label %outer_header [ i32 0, label %exit - i32 1, label %right ] - -exit: - ret void -} - -define void @deeper_nest() { -; CHECK-LABEL: CycleInfo for function: deeper_nest -; CHECK: depth=1: entries(outer_header) outer_latch middle_header inner_header inner_latch -; CHECK: depth=2: entries(middle_header) inner_header inner_latch -; CHECK: depth=3: entries(inner_header) inner_latch -entry: - br label %outer_header - -outer_header: - br label %middle_header - -middle_header: - br label %inner_header - -inner_header: - br i1 undef, label %middle_header, label %inner_latch - -inner_latch: - br i1 undef, label %inner_header, label %outer_latch - -outer_latch: - br i1 undef, label %outer_header, label %exit - -exit: - ret void -} - -define void @irreducible_basic() { -; CHECK-LABEL: CycleInfo for function: irreducible_basic -; CHECK: depth=1: entries(right left) -entry: - br i1 undef, label %left, label %right - -left: - br i1 undef, label %right, label %exit - -right: - br i1 undef, label %left, label %exit - -exit: - ret void -} - -define void @irreducible_mess() { -; CHECK-LABEL: CycleInfo for function: irreducible_mess -; CHECK: depth=1: entries(B A) D C -; CHECK: depth=2: entries(D C A) -; CHECK: depth=3: entries(C A) -entry: - br i1 undef, label %A, label %B - -A: - br i1 undef, label %C, label %D - -B: - br i1 undef, label %C, label %D - -C: - switch i32 undef, label %A [ i32 0, label %D - i32 1, label %exit ] - -D: - switch i32 undef, label %B [ i32 0, label %C - i32 1, label %exit ] - -exit: - ret void -} - -define void @irreducible_into_simple_cycle() { -; CHECK-LABEL: CycleInfo for function: irreducible_into_simple_cycle -; CHECK: depth=1: entries(F C A) E D B -entry: - switch i32 undef, label %A [ i32 0, label %C - i32 1, label %F ] - -A: - br label %B - -B: - br label %C - -C: - br label %D - -D: - br i1 undef, label %E, label %exit - -E: - br label %F - -F: - br i1 undef, label %A, label %exit - -exit: - ret void -} - -define void @irreducible_mountain_bug() { -; CHECK-LABEL: CycleInfo for function: irreducible_mountain_bug -; CHECK: depth=1: entries(while.cond) -; CHECK: depth=2: entries(cond.end61 cond.true49) while.body63 while.cond47 -; CHECK: depth=3: entries(while.body63 cond.true49) while.cond47 -entry: - br i1 undef, label %if.end, label %if.then - -if.end: - br i1 undef, label %if.then7, label %if.else - -if.then7: - br label %if.end16 - -if.else: - br label %if.end16 - -if.end16: - br i1 undef, label %while.cond.preheader, label %if.then39 - -while.cond.preheader: - br label %while.cond - -while.cond: - br i1 undef, label %cond.true49, label %lor.rhs - -cond.true49: - br i1 undef, label %if.then69, label %while.body63 - -while.body63: - br i1 undef, label %exit, label %while.cond47 - -while.cond47: - br i1 undef, label %cond.true49, label %cond.end61 - -cond.end61: - br i1 undef, label %while.body63, label %while.cond - -if.then69: - br i1 undef, label %exit, label %while.cond - -lor.rhs: - br i1 undef, label %cond.end61, label %while.end76 - -while.end76: - br label %exit - -if.then39: - br i1 undef, label %exit, label %if.end.i145 - -if.end.i145: - br i1 undef, label %exit, label %if.end8.i149 - -if.end8.i149: - br label %exit - -if.then: - br i1 undef, label %exit, label %if.end.i - -if.end.i: - br i1 undef, label %exit, label %if.end8.i - -if.end8.i: - br label %exit - -exit: - ret void -} diff --git a/llvm/test/CodeGen/X86/cycle-info.mir b/llvm/test/CodeGen/X86/cycle-info.mir deleted file mode 100644 index 358ccb2c5e73..000000000000 --- a/llvm/test/CodeGen/X86/cycle-info.mir +++ /dev/null @@ -1,629 +0,0 @@ -# RUN: llc -mtriple=x86_64-unknown-linux-gnu -run-pass=print-machine-cycles -o - %s 2>&1 | FileCheck %s - -... ---- -# CHECK-LABEL: MachineCycleInfo for function: empty -name: empty -alignment: 16 -tracksRegLiveness: true -frameInfo: - maxAlignment: 1 -machineFunctionInfo: {} -body: | - bb.0: - RET64 - -... ---- -# CHECK-LABEL: MachineCycleInfo for function: simple -# CHECK: depth=1: entries(bb.1) -name: simple -alignment: 16 -tracksRegLiveness: true -registers: - - { id: 0, class: gr8 } -frameInfo: - maxAlignment: 1 -machineFunctionInfo: {} -body: | - bb.0: - JMP_1 %bb.1 - - bb.1: - %0:gr8 = IMPLICIT_DEF - TEST8ri %0, 1, implicit-def $eflags - JCC_1 %bb.1, 5, implicit $eflags - JMP_1 %bb.2 - - bb.2: - RET64 - -... ---- -# CHECK-LABEL: MachineCycleInfo for function: two_latches -# CHECK: depth=1: entries(bb.1) bb.2 -name: two_latches -alignment: 16 -tracksRegLiveness: true -registers: - - { id: 0, class: gr8 } - - { id: 1, class: gr8 } -frameInfo: - maxAlignment: 1 -machineFunctionInfo: {} -body: | - bb.0: - JMP_1 %bb.1 - - bb.1: - %0:gr8 = IMPLICIT_DEF - TEST8ri %0, 1, implicit-def $eflags - JCC_1 %bb.1, 5, implicit $eflags - JMP_1 %bb.2 - - bb.2: - %1:gr8 = IMPLICIT_DEF - TEST8ri %1, 1, implicit-def $eflags - JCC_1 %bb.3, 5, implicit $eflags - JMP_1 %bb.1 - - bb.3: - RET64 - -... ---- -# CHECK-LABEL: MachineCycleInfo for function: nested_simple -# CHECK: depth=1: entries(bb.1) bb.3 bb.2 -# CHECK: depth=2: entries(bb.2) -name: nested_simple -alignment: 16 -tracksRegLiveness: true -registers: - - { id: 0, class: gr8 } - - { id: 1, class: gr8 } -frameInfo: - maxAlignment: 1 -machineFunctionInfo: {} -body: | - bb.0: - JMP_1 %bb.1 - - bb.1: - JMP_1 %bb.2 - - bb.2: - %0:gr8 = IMPLICIT_DEF - TEST8ri %0, 1, implicit-def $eflags - JCC_1 %bb.2, 5, implicit $eflags - JMP_1 %bb.3 - - bb.3: - %1:gr8 = IMPLICIT_DEF - TEST8ri %1, 1, implicit-def $eflags - JCC_1 %bb.1, 5, implicit $eflags - JMP_1 %bb.4 - - bb.4: - RET64 - -... ---- -# CHECK-LABEL: MachineCycleInfo for function: nested_outer_latch_in_inner_loop -# CHECK: depth=1: entries(bb.1) bb.2 bb.3 -# CHECK: depth=2: entries(bb.2) bb.3 -name: nested_outer_latch_in_inner_loop -alignment: 16 -tracksRegLiveness: true -registers: - - { id: 0, class: gr8 } - - { id: 1, class: gr8 } -frameInfo: - maxAlignment: 1 -machineFunctionInfo: {} -body: | - bb.0: - JMP_1 %bb.1 - - bb.1: - JMP_1 %bb.2 - - bb.2: - %0:gr8 = IMPLICIT_DEF - TEST8ri %0, 1, implicit-def $eflags - JCC_1 %bb.3, 5, implicit $eflags - JMP_1 %bb.1 - - bb.3: - %1:gr8 = IMPLICIT_DEF - TEST8ri %1, 1, implicit-def $eflags - JCC_1 %bb.4, 5, implicit $eflags - JMP_1 %bb.2 - - bb.4: - RET64 - -... ---- -# CHECK-LABEL: MachineCycleInfo for function: sibling_loops -# CHECK: depth=1: entries(bb.1) -# CHECK: depth=1: entries(bb.2) -name: sibling_loops -alignment: 16 -tracksRegLiveness: true -registers: - - { id: 0, class: gr8 } - - { id: 1, class: gr8 } - - { id: 2, class: gr8 } -frameInfo: - maxAlignment: 1 -machineFunctionInfo: {} -body: | - bb.0: - %0:gr8 = IMPLICIT_DEF - TEST8ri %0, 1, implicit-def $eflags - JCC_1 %bb.1, 5, implicit $eflags - JMP_1 %bb.2 - - bb.1: - %2:gr8 = IMPLICIT_DEF - TEST8ri %2, 1, implicit-def $eflags - JCC_1 %bb.1, 5, implicit $eflags - JMP_1 %bb.3 - - bb.2: - %1:gr8 = IMPLICIT_DEF - TEST8ri %1, 1, implicit-def $eflags - JCC_1 %bb.2, 5, implicit $eflags - JMP_1 %bb.3 - - bb.3: - RET64 - -... ---- -# CHECK-LABEL: MachineCycleInfo for function: serial_loops -# CHECK: depth=1: entries(bb.2) -# CHECK: depth=1: entries(bb.1) -name: serial_loops -alignment: 16 -tracksRegLiveness: true -registers: - - { id: 0, class: gr8 } - - { id: 1, class: gr8 } -frameInfo: - maxAlignment: 1 -machineFunctionInfo: {} -body: | - bb.0: - JMP_1 %bb.1 - - bb.1: - %0:gr8 = IMPLICIT_DEF - TEST8ri %0, 1, implicit-def $eflags - JCC_1 %bb.1, 5, implicit $eflags - JMP_1 %bb.2 - - bb.2: - %1:gr8 = IMPLICIT_DEF - TEST8ri %1, 1, implicit-def $eflags - JCC_1 %bb.2, 5, implicit $eflags - JMP_1 %bb.3 - - bb.3: - RET64 - -... ---- -# CHECK-LABEL: MachineCycleInfo for function: nested_sibling_loops -# CHECK: depth=1: entries(bb.1) bb.4 bb.5 bb.3 bb.2 -# CHECK: depth=2: entries(bb.4) bb.5 -# CHECK: depth=2: entries(bb.2) -name: nested_sibling_loops -alignment: 16 -tracksRegLiveness: true -registers: - - { id: 0, class: gr8 } - - { id: 1, class: gr32 } - - { id: 2, class: gr8 } - - { id: 3, class: gr32 } - - { id: 4, class: gr8 } - - { id: 5, class: gr32 } - - { id: 6, class: gr8 } - - { id: 7, class: gr32 } - - { id: 8, class: gr8 } -frameInfo: - maxAlignment: 1 -machineFunctionInfo: {} -body: | - bb.0: - JMP_1 %bb.1 - - bb.1: - %0:gr8 = IMPLICIT_DEF - TEST8ri %0, 1, implicit-def $eflags - JCC_1 %bb.2, 5, implicit $eflags - JMP_1 %bb.3 - - bb.2: - %5:gr32 = MOV32r0 implicit-def dead $eflags - %6:gr8 = COPY %5.sub_8bit - TEST8rr %6, %6, implicit-def $eflags - JCC_1 %bb.2, 5, implicit $eflags - JMP_1 %bb.6 - - bb.6: - %7:gr32 = MOV32r0 implicit-def dead $eflags - %8:gr8 = COPY %7.sub_8bit - TEST8rr %8, %8, implicit-def $eflags - JCC_1 %bb.1, 5, implicit $eflags - JMP_1 %bb.4 - - bb.3: - %1:gr32 = MOV32r0 implicit-def dead $eflags - %2:gr8 = COPY %1.sub_8bit - TEST8rr %2, %2, implicit-def $eflags - JCC_1 %bb.4, 5, implicit $eflags - JMP_1 %bb.5 - - bb.5: - %3:gr32 = MOV32r0 implicit-def dead $eflags - %4:gr8 = COPY %3.sub_8bit - TEST8rr %4, %4, implicit-def $eflags - JCC_1 %bb.3, 5, implicit $eflags - JMP_1 %bb.1 - - bb.4: - RET64 - -... ---- -# CHECK-LABEL: MachineCycleInfo for function: deeper_nest -# CHECK: depth=1: entries(bb.1) bb.5 bb.2 bb.3 bb.4 -# CHECK: depth=2: entries(bb.2) bb.3 bb.4 -# CHECK: depth=3: entries(bb.3) bb.4 -name: deeper_nest -alignment: 16 -tracksRegLiveness: true -registers: - - { id: 0, class: gr8 } - - { id: 1, class: gr8 } - - { id: 2, class: gr8 } -frameInfo: - maxAlignment: 1 -machineFunctionInfo: {} -body: | - bb.0: - JMP_1 %bb.1 - - bb.1: - JMP_1 %bb.2 - - bb.2: - JMP_1 %bb.3 - - bb.3: - %0:gr8 = IMPLICIT_DEF - TEST8ri %0, 1, implicit-def $eflags - JCC_1 %bb.2, 5, implicit $eflags - JMP_1 %bb.4 - - bb.4: - %1:gr8 = IMPLICIT_DEF - TEST8ri %1, 1, implicit-def $eflags - JCC_1 %bb.3, 5, implicit $eflags - JMP_1 %bb.5 - - bb.5: - %2:gr8 = IMPLICIT_DEF - TEST8ri %2, 1, implicit-def $eflags - JCC_1 %bb.1, 5, implicit $eflags - JMP_1 %bb.6 - - bb.6: - RET64 - -... ---- -# CHECK-LABEL: MachineCycleInfo for function: irreducible_basic -# CHECK: depth=1: entries(bb.2 bb.1) -name: irreducible_basic -alignment: 16 -tracksRegLiveness: true -registers: - - { id: 0, class: gr8 } - - { id: 1, class: gr8 } - - { id: 2, class: gr8 } -frameInfo: - maxAlignment: 1 -machineFunctionInfo: {} -body: | - bb.0: - %0:gr8 = IMPLICIT_DEF - TEST8ri %0, 1, implicit-def $eflags - JCC_1 %bb.1, 5, implicit $eflags - JMP_1 %bb.2 - - bb.1: - %1:gr8 = IMPLICIT_DEF - TEST8ri %1, 1, implicit-def $eflags - JCC_1 %bb.2, 5, implicit $eflags - JMP_1 %bb.3 - - bb.2: - %2:gr8 = IMPLICIT_DEF - TEST8ri %2, 1, implicit-def $eflags - JCC_1 %bb.1, 5, implicit $eflags - JMP_1 %bb.3 - - bb.3: - RET64 - -... ---- -# CHECK-LABEL: MachineCycleInfo for function: irreducible_mess -# CHECK: depth=1: entries(bb.2 bb.1) bb.6 bb.5 bb.3 bb.4 -# CHECK: depth=2: entries(bb.5 bb.3 bb.1) bb.4 -# CHECK: depth=3: entries(bb.3 bb.1) bb.4 -name: irreducible_mess -alignment: 16 -tracksRegLiveness: true -registers: - - { id: 0, class: gr8 } - - { id: 1, class: gr8 } - - { id: 2, class: gr32 } - - { id: 3, class: gr8 } - - { id: 4, class: gr32 } - - { id: 5, class: gr8 } - - { id: 6, class: gr32 } - - { id: 7, class: gr8 } - - { id: 8, class: gr32 } - - { id: 9, class: gr8 } - - { id: 10, class: gr8 } -frameInfo: - maxAlignment: 1 -machineFunctionInfo: {} -body: | - bb.0: - %0:gr8 = IMPLICIT_DEF - TEST8ri %0, 1, implicit-def $eflags - JCC_1 %bb.1, 5, implicit $eflags - JMP_1 %bb.2 - - bb.1: - %1:gr8 = IMPLICIT_DEF - TEST8ri %1, 1, implicit-def $eflags - JCC_1 %bb.3, 5, implicit $eflags - JMP_1 %bb.4 - - bb.2: - %10:gr8 = IMPLICIT_DEF - TEST8ri %10, 1, implicit-def $eflags - JCC_1 %bb.3, 5, implicit $eflags - JMP_1 %bb.4 - - bb.3: - %2:gr32 = MOV32r0 implicit-def dead $eflags - %3:gr8 = COPY %2.sub_8bit - TEST8rr %3, %3, implicit-def $eflags - JCC_1 %bb.4, 5, implicit $eflags - JMP_1 %bb.6 - - bb.6: - %4:gr32 = MOV32r0 implicit-def dead $eflags - %5:gr8 = COPY %4.sub_8bit - TEST8rr %5, %5, implicit-def $eflags - JCC_1 %bb.5, 5, implicit $eflags - JMP_1 %bb.1 - - bb.4: - %6:gr32 = MOV32r0 implicit-def dead $eflags - %7:gr8 = COPY %6.sub_8bit - TEST8rr %7, %7, implicit-def $eflags - JCC_1 %bb.3, 5, implicit $eflags - JMP_1 %bb.7 - - bb.7: - successors: %bb.5, %bb.2 - - %8:gr32 = MOV32r0 implicit-def dead $eflags - %9:gr8 = COPY %8.sub_8bit - TEST8rr %9, %9, implicit-def $eflags - JCC_1 %bb.2, 5, implicit $eflags - JMP_1 %bb.5 - - bb.5: - RET64 - -... ---- -# CHECK-LABEL: MachineCycleInfo for function: irreducible_into_simple_cycle -# CHECK: depth=1: entries(bb.2 bb.7 bb.4) bb.6 bb.5 bb.3 -name: irreducible_into_simple_cycle -alignment: 16 -tracksRegLiveness: true -registers: - - { id: 0, class: gr32 } - - { id: 1, class: gr8 } - - { id: 2, class: gr32 } - - { id: 3, class: gr8 } - - { id: 4, class: gr8 } - - { id: 5, class: gr8 } -frameInfo: - maxAlignment: 1 -machineFunctionInfo: {} -body: | - bb.0: - %0:gr32 = MOV32r0 implicit-def dead $eflags - %1:gr8 = COPY %0.sub_8bit - TEST8rr %1, %1, implicit-def $eflags - JCC_1 %bb.3, 5, implicit $eflags - JMP_1 %bb.8 - - bb.8: - %2:gr32 = MOV32r0 implicit-def dead $eflags - %3:gr8 = COPY %2.sub_8bit - TEST8rr %3, %3, implicit-def $eflags - JCC_1 %bb.6, 5, implicit $eflags - JMP_1 %bb.1 - - bb.1: - JMP_1 %bb.2 - - bb.2: - JMP_1 %bb.3 - - bb.3: - JMP_1 %bb.4 - - bb.4: - %4:gr8 = IMPLICIT_DEF - TEST8ri %4, 1, implicit-def $eflags - JCC_1 %bb.5, 5, implicit $eflags - JMP_1 %bb.7 - - bb.5: - JMP_1 %bb.6 - - bb.6: - %5:gr8 = IMPLICIT_DEF - TEST8ri %5, 1, implicit-def $eflags - JCC_1 %bb.1, 5, implicit $eflags - JMP_1 %bb.7 - - bb.7: - RET64 - -... ---- -# CHECK-LABEL: MachineCycleInfo for function: irreducible_mountain_bug -# CHECK: depth=1: entries(bb.6) bb.11 bb.10 bb.8 bb.7 bb.9 bb.12 -# CHECK: depth=2: entries(bb.10 bb.7) bb.8 bb.9 -# CHECK: depth=3: entries(bb.8 bb.7) bb.9 -name: irreducible_mountain_bug -alignment: 16 -tracksRegLiveness: true -registers: - - { id: 0, class: gr8 } - - { id: 1, class: gr8 } - - { id: 2, class: gr8 } - - { id: 3, class: gr8 } - - { id: 4, class: gr8 } - - { id: 5, class: gr8 } - - { id: 6, class: gr8 } - - { id: 7, class: gr8 } - - { id: 8, class: gr8 } - - { id: 9, class: gr8 } - - { id: 10, class: gr8 } - - { id: 11, class: gr8 } - - { id: 12, class: gr8 } - - { id: 13, class: gr8 } -frameInfo: - maxAlignment: 1 -machineFunctionInfo: {} -body: | - bb.0: - %0:gr8 = IMPLICIT_DEF - TEST8ri %0, 1, implicit-def $eflags - JCC_1 %bb.1, 5, implicit $eflags - JMP_1 %bb.17 - - bb.1: - %3:gr8 = IMPLICIT_DEF - TEST8ri %3, 1, implicit-def $eflags - JCC_1 %bb.2, 5, implicit $eflags - JMP_1 %bb.3 - - bb.2: - JMP_1 %bb.4 - - bb.3: - JMP_1 %bb.4 - - bb.4: - %4:gr8 = IMPLICIT_DEF - TEST8ri %4, 1, implicit-def $eflags - JCC_1 %bb.5, 5, implicit $eflags - JMP_1 %bb.14 - - bb.5: - JMP_1 %bb.6 - - bb.6: - %7:gr8 = IMPLICIT_DEF - TEST8ri %7, 1, implicit-def $eflags - JCC_1 %bb.7, 5, implicit $eflags - JMP_1 %bb.12 - - bb.7: - %9:gr8 = IMPLICIT_DEF - TEST8ri %9, 1, implicit-def $eflags - JCC_1 %bb.11, 5, implicit $eflags - JMP_1 %bb.8 - - bb.8: - %10:gr8 = IMPLICIT_DEF - TEST8ri %10, 1, implicit-def $eflags - JCC_1 %bb.20, 5, implicit $eflags - JMP_1 %bb.9 - - bb.9: - %11:gr8 = IMPLICIT_DEF - TEST8ri %11, 1, implicit-def $eflags - JCC_1 %bb.7, 5, implicit $eflags - JMP_1 %bb.10 - - bb.10: - %12:gr8 = IMPLICIT_DEF - TEST8ri %12, 1, implicit-def $eflags - JCC_1 %bb.8, 5, implicit $eflags - JMP_1 %bb.6 - - bb.11: - %13:gr8 = IMPLICIT_DEF - TEST8ri %13, 1, implicit-def $eflags - JCC_1 %bb.20, 5, implicit $eflags - JMP_1 %bb.6 - - bb.12: - %8:gr8 = IMPLICIT_DEF - TEST8ri %8, 1, implicit-def $eflags - JCC_1 %bb.10, 5, implicit $eflags - JMP_1 %bb.13 - - bb.13: - JMP_1 %bb.20 - - bb.14: - %5:gr8 = IMPLICIT_DEF - TEST8ri %5, 1, implicit-def $eflags - JCC_1 %bb.20, 5, implicit $eflags - JMP_1 %bb.15 - - bb.15: - %6:gr8 = IMPLICIT_DEF - TEST8ri %6, 1, implicit-def $eflags - JCC_1 %bb.20, 5, implicit $eflags - JMP_1 %bb.16 - - bb.16: - JMP_1 %bb.20 - - bb.17: - %1:gr8 = IMPLICIT_DEF - TEST8ri %1, 1, implicit-def $eflags - JCC_1 %bb.20, 5, implicit $eflags - JMP_1 %bb.18 - - bb.18: - %2:gr8 = IMPLICIT_DEF - TEST8ri %2, 1, implicit-def $eflags - JCC_1 %bb.20, 5, implicit $eflags - JMP_1 %bb.19 - - bb.19: - JMP_1 %bb.20 - - bb.20: - RET64 - -... -- GitLab