[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / llvm / utils / pipeline.py
blob7e49f711d3e7274843c3267f4dee6b911f2bccf3
1 # Automatically formatted with yapf (https://github.com/google/yapf)
2 """Utility functions for creating and manipulating LLVM 'opt' NPM pipeline objects."""
5 def fromStr(pipeStr):
6 """Create pipeline object from string representation."""
7 stack = []
8 curr = []
9 tok = ''
10 kind = ''
11 for c in pipeStr:
12 if c == ',':
13 if tok != '':
14 curr.append([None, tok])
15 tok = ''
16 elif c == '(':
17 stack.append([kind, curr])
18 kind = tok
19 curr = []
20 tok = ''
21 elif c == ')':
22 if tok != '':
23 curr.append([None, tok])
24 tok = ''
25 oldKind = kind
26 oldCurr = curr
27 [kind, curr] = stack.pop()
28 curr.append([oldKind, oldCurr])
29 else:
30 tok += c
31 if tok != '':
32 curr.append([None, tok])
33 return curr
36 def toStr(pipeObj):
37 """Create string representation of pipeline object."""
38 res = ''
39 lastIdx = len(pipeObj) - 1
40 for i, c in enumerate(pipeObj):
41 if c[0]:
42 res += c[0] + '('
43 res += toStr(c[1])
44 res += ')'
45 else:
46 res += c[1]
47 if i != lastIdx:
48 res += ','
49 return res
52 def count(pipeObj):
53 """Count number of passes (pass-managers excluded) in pipeline object."""
54 cnt = 0
55 for c in pipeObj:
56 if c[0]:
57 cnt += count(c[1])
58 else:
59 cnt += 1
60 return cnt
63 def split(pipeObj, splitIndex):
64 """Create two new pipeline objects by splitting pipeObj in two directly after pass with index splitIndex."""
65 def splitInt(src, splitIndex, dstA, dstB, idx):
66 for s in src:
67 if s[0]:
68 dstA2 = []
69 dstB2 = []
70 idx = splitInt(s[1], splitIndex, dstA2, dstB2, idx)
71 dstA.append([s[0], dstA2])
72 dstB.append([s[0], dstB2])
73 else:
74 if idx <= splitIndex:
75 dstA.append([None, s[1]])
76 else:
77 dstB.append([None, s[1]])
78 idx += 1
79 return idx
81 listA = []
82 listB = []
83 splitInt(pipeObj, splitIndex, listA, listB, 0)
84 return [listA, listB]
87 def remove(pipeObj, removeIndex):
88 """Create new pipeline object by removing pass with index removeIndex from pipeObj."""
89 def removeInt(src, removeIndex, dst, idx):
90 for s in src:
91 if s[0]:
92 dst2 = []
93 idx = removeInt(s[1], removeIndex, dst2, idx)
94 dst.append([s[0], dst2])
95 else:
96 if idx != removeIndex:
97 dst.append([None, s[1]])
98 idx += 1
99 return idx
101 dst = []
102 removeInt(pipeObj, removeIndex, dst, 0)
103 return dst
106 def copy(srcPipeObj):
107 """Create copy of pipeline object srcPipeObj."""
108 def copyInt(dst, src):
109 for s in src:
110 if s[0]:
111 dst2 = []
112 copyInt(dst2, s[1])
113 dst.append([s[0], dst2])
114 else:
115 dst.append([None, s[1]])
117 dstPipeObj = []
118 copyInt(dstPipeObj, srcPipeObj)
119 return dstPipeObj
122 def prune(srcPipeObj):
123 """Create new pipeline object by removing empty pass-managers (those with count = 0) from srcPipeObj."""
124 def pruneInt(dst, src):
125 for s in src:
126 if s[0]:
127 if count(s[1]):
128 dst2 = []
129 pruneInt(dst2, s[1])
130 dst.append([s[0], dst2])
131 else:
132 dst.append([None, s[1]])
134 dstPipeObj = []
135 pruneInt(dstPipeObj, srcPipeObj)
136 return dstPipeObj
139 if __name__ == "__main__":
140 import unittest
142 class Test(unittest.TestCase):
143 def test_0(self):
144 pipeStr = 'a,b,A(c,B(d,e),f),g'
145 pipeObj = fromStr(pipeStr)
147 self.assertEqual(7, count(pipeObj))
149 self.assertEqual(pipeObj, pipeObj)
150 self.assertEqual(pipeObj, prune(pipeObj))
151 self.assertEqual(pipeObj, copy(pipeObj))
153 self.assertEqual(pipeStr, toStr(pipeObj))
154 self.assertEqual(pipeStr, toStr(prune(pipeObj)))
155 self.assertEqual(pipeStr, toStr(copy(pipeObj)))
157 [pipeObjA, pipeObjB] = split(pipeObj, 3)
158 self.assertEqual('a,b,A(c,B(d))', toStr(pipeObjA))
159 self.assertEqual('A(B(e),f),g', toStr(pipeObjB))
161 self.assertEqual('b,A(c,B(d,e),f),g', toStr(remove(pipeObj, 0)))
162 self.assertEqual('a,b,A(c,B(d,e),f)', toStr(remove(pipeObj, 6)))
164 pipeObjC = remove(pipeObj, 4)
165 self.assertEqual('a,b,A(c,B(d),f),g', toStr(pipeObjC))
166 pipeObjC = remove(pipeObjC, 3)
167 self.assertEqual('a,b,A(c,B(),f),g', toStr(pipeObjC))
168 pipeObjC = prune(pipeObjC)
169 self.assertEqual('a,b,A(c,f),g', toStr(pipeObjC))
171 unittest.main()
172 exit(0)