aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeddy <ted.sybil@gmail.com>2014-05-28 23:36:59 +0800
committerTeddy <ted.sybil@gmail.com>2014-05-28 23:36:59 +0800
commitff48776ab7a4a440f348c1eca400529b50d73beb (patch)
tree1534eef83c86c55d05eba2f50c2f1f69e71824f3
parentd765f0e644528a07da8985822eda61e7454081ff (diff)
move docs to a seperate dir
-rw-r--r--cibic.pdfbin131330 -> 0 bytes
-rw-r--r--doc/all.gp61
-rw-r--r--doc/cibic.pdfbin0 -> 683955 bytes
-rw-r--r--doc/cibic.tex (renamed from cibic.tex)225
-rw-r--r--doc/conv.py20
-rw-r--r--doc/g1.gv10
-rw-r--r--doc/g2.gv10
-rw-r--r--doc/g3.gv16
-rw-r--r--doc/res.csv35
9 files changed, 320 insertions, 57 deletions
diff --git a/cibic.pdf b/cibic.pdf
deleted file mode 100644
index 80c443c..0000000
--- a/cibic.pdf
+++ /dev/null
Binary files differ
diff --git a/doc/all.gp b/doc/all.gp
new file mode 100644
index 0000000..ad0322d
--- /dev/null
+++ b/doc/all.gp
@@ -0,0 +1,61 @@
+reset
+# define axis
+# remove border on top and right and set color to gray
+set style line 11 lc rgb '#808080' lt 1
+set border 3 back ls 11
+set tics nomirror
+# define grid
+set style line 12 lc rgb '#808080' lt 0 lw 1
+set grid back ls 12
+
+set style line 11 linecolor rgb '#dd181f' linetype 1 linewidth 2 # red
+set style line 13 linecolor rgb '#aaaaaa' linetype 1 linewidth 1 # red
+set style line 12 linecolor rgb '#0060ad' linetype 1 linewidth 2 # blue
+
+set style line 1 lc rgb '#800000' lt 1 lw 2
+set style line 2 lc rgb '#ff0000' lt 1 lw 2
+set style line 3 lc rgb '#ff4500' lt 1 lw 2
+set style line 4 lc rgb '#ffa500' lt 1 lw 2
+set style line 5 lc rgb '#006400' lt 1 lw 2
+set style line 6 lc rgb '#0000ff' lt 1 lw 2
+set style line 7 lc rgb '#9400d3' lt 1 lw 2
+
+set border lw 2
+set title "Normalized Benchmark Result of the Test Cases"
+set terminal "pngcairo" size 800, 480 enhanced
+set key top left
+set output "all.png"
+set xlabel "Test Cases"
+set ylabel "Normalized Instruction (self / best)"
+set xrange [:39]
+set yrange [:10]
+plot for [i=2:35] 'all.csv' u :((column(i))) with lines ls 13 title '', \
+ for [i=6:6] 'all.csv' u :((column(i))) with lines ls 11 title 'zzy7896321', \
+ for [i=5:5] 'all.csv' u :((column(i))) with lines ls 7 title 'ascii991218', \
+ for [i=1:1] 'all.csv' u :((column(i))) with lines ls 12 title 'Determinant (CIBIC)'
+
+set border lw 2
+set title "Normalized Benchmark Result of the Test Cases"
+set terminal "pngcairo" size 800, 480 enhanced
+set key top left
+set output "all2.png"
+set xlabel "Test Cases"
+set ylabel "Normalized Instruction (self / best)"
+set yrange [:10]
+plot for [i=2:35] 'all.csv' u :((column(i))) with lines ls 13 title '', \
+ for [i=4:4] 'all.csv' u :((column(i))) with lines ls 5 title 'cycycy', \
+ for [i=3:3] 'all.csv' u :((column(i))) with lines ls 3 title 'jiziwei', \
+ for [i=1:1] 'all.csv' u :((column(i))) with lines ls 12 title 'Determinant (CIBIC)'
+
+set border lw 2
+set title "Normalized Benchmark Result of the Test Cases"
+set terminal "pngcairo" size 800, 480 enhanced
+set key top left
+set output "all3.png"
+set xlabel "Test Cases"
+set ylabel "Normalized Instruction (self / best)"
+set yrange [:10]
+plot for [i=2:35] 'all.csv' u :((column(i))) with lines ls 13 title '', \
+ for [i=7:7] 'all.csv' u :((column(i))) with lines ls 3 title 'daerduomkch', \
+ for [i=2:2] 'all.csv' u :((column(i))) with lines ls 1 title 'sadkangaroo', \
+ for [i=1:1] 'all.csv' u :((column(i))) with lines ls 12 title 'Determinant (CIBIC)'
diff --git a/doc/cibic.pdf b/doc/cibic.pdf
new file mode 100644
index 0000000..7daaf46
--- /dev/null
+++ b/doc/cibic.pdf
Binary files differ
diff --git a/cibic.tex b/doc/cibic.tex
index 35d795c..2e14dc0 100644
--- a/cibic.tex
+++ b/doc/cibic.tex
@@ -3,7 +3,7 @@
\usepackage{xeCJK, fontspec}
\usepackage{amsmath, verbatim}
\usepackage{setspace, float}
-\usepackage{graphicx, wrapfig}
+\usepackage{graphicx, wrapfig, algorithmicx}
\usepackage{rotating, enumerate, minted, fancyvrb, longtable}
\usepackage[left=1in, right=1in]{geometry}
\usepackage[font=small]{caption}
@@ -61,17 +61,18 @@ boilerplate text which contains C code fragments to be filled in the generated
lexer/parser. The best practice, I suggest, is to avoid embedding too much
concrete code in the boilerplate. Instead, we shall write well-designed
functions in a separate file (``\texttt{ast.c}'' in CIBIC) and invoke functions
-in the boilerplate. The reason is that it is almost not practical nor convenient
-to debug the generated lexer or parser. Using the seperation method, we can set
-up breakpoints in the seperate file easily and debug on the fly. The
-declarations of all functions that may be invoked during parsing can be found in
-``\texttt{ast.h}''.
-
-It requires a little more effort to track the location of each token using Flex.
-Luckily, Flex provides with a macro called ``\texttt{YY\_USER\_ACTION}'' to let
-the user do some extra actions after each token is read. So I maintained a
-global variable ``\texttt{yycolumn}'' to keep the current column, a global char
-array ``\texttt{linebuff}'' to buffer the text being read for error report.
+in the boilerplate. The reason is that it is almost not practical nor
+convenient to debug the generated lexer or parser. Using the seperation method,
+we can set up breakpoints in the seperate file easily and debug on the fly. The
+declarations of all functions that may be invoked during parsing can be found
+in``\texttt{ast.h}''.
+
+It requires a little more effort to track the location of each token using
+Flex. Luckily, Flex provides with a macro called ``\texttt{YY\_USER\_ACTION}''
+to let the user do some extra actions after each token is read. So I maintained
+a global variable ``\texttt{yycolumn}'' to keep the current column, a global
+char array ``\texttt{linebuff}'' to buffer the text being read for error
+report.
\begin{listing}[H]
\centering
\RecustomVerbatimEnvironment{Verbatim}{BVerbatim}{}
@@ -164,13 +165,13 @@ information.
The key data structures in the semantic checking are \textbf{symbol tables}.
Symbol tables maintain variables and types in different scopes across different
-name spaces. When a variable is defined, the corresponding type specifer will be
-checked and binds to the variable. Also, when the scope ends, all variable
+name spaces. When a variable is defined, the corresponding type specifer will
+be checked and binds to the variable. Also, when the scope ends, all variable
bindings living within the scope will be removed from the table. Although they
are removed from the table, the bindings are still referenced by some nodes on
the AST, so that the AST becomes ``\textbf{annotated AST}''. In CIBIC, the
-variable reference is stored in ``\texttt{ext.var}'' field of ``\texttt{CNode}''
-and the type information of an subexpression is annotated at
+variable reference is stored in ``\texttt{ext.var}'' field of
+``\texttt{CNode}'' and the type information of an subexpression is annotated at
``\texttt{ext.type}''. Thus, in a word, symbol tables stores all symbols that
are currently \textbf{visible}.
@@ -677,6 +678,7 @@ build_intervals();
register_alloc();
\end{minted}
\caption{Workflow of IR in CIBIC}
+ \label{list:workflow}
\end{listing}
\subsection{Single Static Assignment Form}
@@ -686,16 +688,16 @@ once}. The property can simplify the liveness analysis and optimization, since
all variables are assigned only once so the ``define-use'' relationship is much
clearer that the original IR.
-However, it is not trival to convert an IR to SSA form, mainly because of the
+However, it is not trivial to convert an IR to SSA form, mainly because of the
``merging issue''. In figure \ref{fig:phi_function}, the control flow branches
-at the if statement and merges again when getting out of if. The question is,
-should we use \texttt{x\_1} or \texttt{x\_2} in the \texttt{y = x + 1}
-statement? The answer is, it is only known at runtime. So a ``phi-function''
-\texttt{x\_3 = phi(x\_1, x\_2)} will be inserted at the merge point to wrap two
-possibilities. Unfortunately, not only does this circumstance appear in if
-statement, but also exist in loops. How do we know where we should add an
-phi-function for certain variable? The answer is we can just insert
-phi-functions at dominance frontiers in the control flow graph.
+at the \texttt{if} statement and merges again when getting out of if. The
+question is, should we use \texttt{x\_1} or \texttt{x\_2} in the \texttt{y = x
++ 1} statement? The answer is, it is only known at runtime. So a
+``phi-function'' \texttt{x\_3 = phi(x\_1, x\_2)} will be inserted at the merge
+point to wrap two possibilities. Unfortunately, not only does this
+circumstance appear in if statement, but also exist in loops. How do we know
+where we should add an phi-function for certain variable? The answer is we can
+just insert phi-functions at dominance frontiers in the control flow graph.
\subsection{Phi-functions}
There are several ways of computing dominance frontiers of a control flow
graph. But they all first construct the dominator tree and then deduce the
@@ -720,10 +722,10 @@ implement.
\label{fig:phi_function}
\end{figure}
\subsection{Register Allocation}
-CIBIC uses linear scan register allocation \cite{moe02} to allocate registers \emph{before
-translating out of SSA form}. This method is different from traditional one and
-can make use of lifetime holes and instruction weights to improve the quality of
-the allocation.
+CIBIC uses linear scan register allocation \cite{moe02} to allocate registers
+\emph{before translating out of SSA form}. This method is different from
+traditional one and can make use of lifetime holes and instruction weights to
+improve the quality of the allocation.
To run the allocation algorithm, we shall first compute live intervals.
Unfortunately, the pseudo-code provided in the paper \cite{moe02} does not take
@@ -731,7 +733,9 @@ the loop cases into account. In another paper \cite{wimmer10}, I found the
correct algorithm for coping with loops. Unfortunately, the pseudo-code in two
papers are written in different forms and have different concepts in some
details. So I learned from both of them and got my own algorithm (almost like
-the one in paper \cite{moe02}).
+the one in paper \cite{moe02}). Since the graph is traversed \textbf{only
+once}, the implementation is quite efficient (the traditional method for
+non-SSA IR requires iteration thus the time complexity is not guaranteed).
In linear scan algorithm described in paper \cite{moe02}, we should maintain
four sets: unhandled, handled, active, inactive. However, for the
@@ -746,49 +750,153 @@ set and the sentinel node helps us to move to another set conveniently. The
algorithm also requires a pre-calculated weight of each interval (computed from
the accesses to the interval) which helps to decide the spilled variable.
\section{Performance and Optimization}
-\subsection{Compile Time}
+\subsection{Compilation Speed}
CIBIC compiles very fast for all the given source code and some additional test
cases. It costs CIBIC 0.10 second to compile all 52 programs, while gcc spends
1.90 seconds to complete in the same testing environment. Although the test may
not be complete or fair (since gcc is a much more sophisticated compiler), the
-result does show a decent and promising compile speed.
-\subsection{Compile Quality}
+result does show a decent and promising compilation speed.
+\subsection{Compilation Quality}
In the final examination, the performance of MIPS assembly generated by CIBIC
surpasses the ones generated by most of my classmates' Java-implemented
-compilers. It is worth mentioning that all of those few (just about three or
-four) compilers that produces better code are written in Java and none of them
-always generates better code than CIBIC. Also, in the circumstances where the
-code generated by CIBIC is not the best, the runtime difference between the
-best performance code and the one by CIBIC is small. Moreover, as far as I
-know, those compiler make use of inline optimization (not fully implemented)
-which may be very effective for some special code. However, CIBIC does not
-implement any form of inline optimization due to the limited time (To implement
-a decent inline optimization for an SSA-based and C-implemented compiler
-requires some extra work). Finally, I would like to aruge that all test cases
-provied by teaching assistants may not be complete or convincing. The major
-design flaw is all functions are very short and only have one or two nested if
-statement or loops (except test case: ``superloop''). Therefore, the advantage
-of SSA (especially the advanced register allocation algorithm) is not shown
-very well.
+compilers. It is worth mentioning that all of those few compilers that produces
+better code are written in Java and none of them always generates better code
+than CIBIC. Also, in the circumstances where the code generated by CIBIC is not
+the best, the runtime difference between the best performance code and the one
+by CIBIC is small. Moreover, as far as I know, those compiler make use of (not
+fully implemented) inline optimization which may be very effective for some
+special code. However, CIBIC does not implement any form of inline optimization
+due to the limited time (To implement a decent inline optimization for an
+SSA-based and C-implemented compiler requires some extra work). Finally, I
+would like to argue that all test cases provided by teaching assistants may not
+be complete or convincing. The major design flaw is all functions are very
+short and only have one or two nested \texttt{if} statement or loops (except
+test case: ``superloop''). Therefore, the advantage of SSA (especially the
+advanced register allocation algorithm) is not shown very well.
+
+\begin{figure}[H]
+ \centering
+ \includegraphics[scale=0.5]{all.png}
+\end{figure}
+\begin{figure}[H]
+ \centering
+ \includegraphics[scale=0.5]{all2.png}
+\end{figure}
+\begin{figure}[H]
+ \centering
+ \includegraphics[scale=0.5]{all3.png}
+\end{figure}
+
+The above figures show the ``normalized instruction'' for each compiler
+implementation with respect to different test cases. The ``normalized
+instruction'' is obtained by dividing the number of instructions by the best
+for the same test case, thus the lower, the better. There are 40 test cases
+taken into account. Some good implementations are picked out and bolded in the
+figures, while others are simply colored gray.
+
+Although CIBIC does not generate the best code in some test cases, the overall
+code quality is very good. Moreover, CIBIC has not implemented inline
+optimization yet. As I know, compilers that are presented in bolded lines in
+the second and the third figure all implement inline optimization, and before
+the optimization, their performance are not as good as CIBIC. Therefore CIBIC
+could do much more better.
+
\subsection{Optimization}
CIBIC implements the following optimizations:
\begin{itemize}
\item constant propagation
\item dead code elimination
\item strength reduction
- \item common subexpression eliminiation
+ \item common subexpression elimination
\end{itemize}
-Unfortunately, these optimization do not seems to be very effective to the
+Unfortunately, these optimization do not seem to be very effective to the
given test cases (although some may be effective to some specific test cases).
-However, the assembly level optimization does have a considerable effect. Some important techinques are:
+However, the assembly level optimization does have a considerable effect. Some
+important techniques are:
\begin{itemize}
- \item reduce the use of \texttt{seq} and \texttt{sne} by fusing them with subsequent \texttt{beq} or \texttt{bne}
+ \item reduce the use of \texttt{seq} and \texttt{sne} by fusing them with
+ subsequent \texttt{beq} or \texttt{bne}
\item reduce the load of immediates
- \item fuse the short-circuit operators and subsequent branch together (on the one hand it can reduce one or two extra jumps, on the other hand, the dominance of CFG may change so that common subexpression optimization can optimize more)
+ \item fuse the short-circuit operators and subsequent branch together (on
+ the one hand it can reduce one or two extra jumps, on the other hand,
+ the dominance of CFG may change so that common subexpression
+ optimization can optimize more)
\end{itemize}
-We are not going to discuss optimization effectiveness in detail because all optimizations used by CIBIC are traditional. Instead, code snippets are presented and explained below to reveal \textbf{inappropriate naive implementation of some optimizations may be wrong}.
+We are not going to discuss optimization effectiveness in detail because all
+optimizations used by CIBIC are traditional. Instead, code snippets are
+presented and explained below to reveal \textbf{inappropriate naive
+implementation of some optimizations may be wrong}.
+
+Constant propagation could be safely applied if there were not any indirect
+modification to the propagated variable. Unfortunately, this is not always true.
+A typical indirection modification is via calling a function which modifies a
+global variable. Because of the function call, the modification is hidden from
+the compiler. Another common indirect modification is done via a pointer. A
+direct approach to get over these problem is to prevent the propagation over a
+function call and to mark those variable whose address is being referenced (by
+``\texttt{\&}'' operator) to disable the propagation of their value.
+
+The same things may also happen in common subexpression elimination. The code
+below demonstrates two typical situations in which the aggressive elimination
+may produce a wrong result.
+\begin{figure}[H]
+ \begin{minipage}{0.4\textwidth}
+ \RecustomVerbatimEnvironment{Verbatim}{BVerbatim}{}
+ \centering
+ \begin{minted}{c}
+int N = 0;
+void f() { N = 2; }
+int main() {
+ int a, b;
+ a = N + 1;
+ f();
+ b = N + 1;
+ printf("%d\n", b); /* 3 */
+}
+ \end{minted}
+ \end{minipage}
+ % \centering
+ \begin{minipage}{0.5\textwidth}
+ \RecustomVerbatimEnvironment{Verbatim}{BVerbatim}{}
+ \centering
+\begin{minted}{c}
+ int flag = 0;
+ int check(int x, int y) {
+ return x > 0 && y > 0 && (flag ^= 1);
+ }
+ int main() {
+ int x = 1, y = 2;
+ printf("%d\n", check(x, y)); /* 1 */
+ printf("%d\n", check(x, y)); /* 0 */
+ printf("%d\n", check(x, y)); /* 1 */
+ }
+\end{minted}
+ \end{minipage}
+ \label{fig:cse}
+\end{figure}
+Global common subexpression elimination should be performed while walking down
+the dominator tree \cite{sassa07}. Luckily, The dominator tree can be easily
+obtained because it is an important by-product of SSA construction.
+
+In CIBIC, all optimizations need to be performed only once or twice as shown in
+listing \ref{list:workflow}. Because the implemented optimizations do not
+require iteration.
+
+\section{Conclusion}
+CIBIC is a simple but efficient C compiler implementation in C. It supports key
+characteristics of C language such as structs/unions, arrays, and various type
+of pointers. \texttt{typedef}, a very useful syntactic sugar is also
+implemented in CIBIC. Furthermore, CIBIC makes use of SSA to generate code of
+decent quality. As a lightweight compiler, it compiles much faster than gcc
+(gcc implements a lot more features though).
+
+Some standard syntax and features written in C are not supported by CIBIC:
+\texttt{enum}, \texttt{switch}, linking, preprocessing (such as
+\texttt{\#define}), etc. However, it is very possible to extend CIBIC to
+support these features. Some, for example \texttt{switch} statements are easy
+to be added.
\begin{thebibliography}{9}
\bibitem{grune12}
Grune, Dick, et al. Modern Compiler Design. Springer, 2012.
@@ -803,12 +911,15 @@ We are not going to discuss optimization effectiveness in detail because all opt
Cooper, Keith D., Timothy J. Harvey, and Ken Kennedy. ``A simple, fast
dominance algorithm.'' Software Practice \& Experience 4 (2001): 1-10.
\bibitem{moe02}
- M\"ossenb\:ock, Hanspeter, and Michael Pfeiffer. ``Linear scan register allocation
- in the context of SSA form and register constraints.'' Compiler Construction.
- Springer Berlin Heidelberg, 2002.
+ M\"ossenb\:ock, Hanspeter, and Michael Pfeiffer. ``Linear scan register
+ allocation in the context of SSA form and register constraints.''
+ Compiler Construction. Springer Berlin Heidelberg, 2002.
\bibitem{wimmer10}
Wimmer, Christian, and Michael Franz. ``Linear scan register allocation
on SSA form.'' Proceedings of the 8th annual IEEE/ACM international
symposium on Code generation and optimization. ACM, 2010.
+ \bibitem{sassa07}
+ Tokyo Institute of Technology. Optimization in Static Single Assignment
+ Form
\end{thebibliography}
\end{document}
diff --git a/doc/conv.py b/doc/conv.py
new file mode 100644
index 0000000..4689d9b
--- /dev/null
+++ b/doc/conv.py
@@ -0,0 +1,20 @@
+from sys import stdout
+f = open("res.csv", "r")
+matrix = list()
+for line in f.readlines():
+ matrix.append([float(x) for x in line.split()[1:]])
+col = len(matrix[0])
+row = len(matrix)
+inf = 1e9
+for j in xrange(col):
+ best = inf
+ for i in xrange(row):
+ if matrix[i][j] < best:
+ best = matrix[i][j]
+ for i in xrange(row):
+ if matrix[i][j] > inf:
+ r = '-'
+ else:
+ r = str(matrix[i][j] / best)
+ stdout.write('{0} '.format(r))
+ stdout.write('\n')
diff --git a/doc/g1.gv b/doc/g1.gv
new file mode 100644
index 0000000..e762143
--- /dev/null
+++ b/doc/g1.gv
@@ -0,0 +1,10 @@
+digraph G {
+ a [shape = box, fontname = "monospace", label = "a = x_0\nif (a == 0) goto _L1"];
+ b [shape = box, fontname = "monospace", label = "x_1 = 1"];
+ c [shape = box, fontname = "monospace", label = "x_2 = 2"];
+ d [shape = box, fontname = "monospace", label = "y_0 = x_? + 1"];
+ a -> b;
+ a -> c;
+ b -> d;
+ c -> d;
+}
diff --git a/doc/g2.gv b/doc/g2.gv
new file mode 100644
index 0000000..76f9340
--- /dev/null
+++ b/doc/g2.gv
@@ -0,0 +1,10 @@
+digraph G {
+ a [shape = box, fontname = "monospace", label = "a = x_0\nif (a == 0) goto _L1"];
+ b [shape = box, fontname = "monospace", label = "x_1 = 1"];
+ c [shape = box, fontname = "monospace", label = "x_2 = 2"];
+ d [shape = box, fontname = "monospace", label = "x_3 = phi(x_1, x_2)\ny_0 = x_3 + 1"];
+ a -> b;
+ a -> c;
+ b -> d;
+ c -> d;
+}
diff --git a/doc/g3.gv b/doc/g3.gv
new file mode 100644
index 0000000..7dcf088
--- /dev/null
+++ b/doc/g3.gv
@@ -0,0 +1,16 @@
+digraph G {
+ a [shape = box, fontname = "monospace", label = "struct A"];
+ b [shape = box, fontname = "monospace", label = "b :: struct B"];
+ c [shape = box, fontname = "monospace", label = "i :: int"];
+ d [shape = box, fontname = "monospace", label = "j :: int"];
+ e [shape = box, fontname = "monospace", label = "x :: int"];
+ f [shape = box, fontname = "monospace", label = "y :: int"];
+ g [shape = box, fontname = "monospace", label = "next :: ptr"];
+ a -> b;
+ b -> c;
+ b -> d;
+ a -> e;
+ a -> f;
+ a -> g;
+ g -> a;
+}
diff --git a/doc/res.csv b/doc/res.csv
new file mode 100644
index 0000000..f1511dc
--- /dev/null
+++ b/doc/res.csv
@@ -0,0 +1,35 @@
+Determinant 268281 16494 485659 1326 145 231 141295 45550 171228 6197660 19 8647871 11943104 11293887 1202 71 707368 137 92 5605161 2562 5413 71 5383633 35 2046880 1968964 1332549 90066 358747 35 12492 89 59420 321 791769 1485528 3839587 587055 2942
+sadkangaroo 470199 12649 898668 12350 129 219 147434 48101 144124 9388990 17 5877835 8009492 9766599 1484 53 780277 131 76 6519697 2298 6224 77 9056881 47 2791288 2714008 1814324 81927 463938 26 6664 87 54927 128 744401 1364259 2691339 756016 2047
+jiziwei 284216 10980 481228 1297 124 208 174060 67544 142831 4988517 24 4796844 6558290 5984933 1179 75 665791 140 94 5190729 2283 5241 80 5394620 42 1863026 1787792 1373720 71398 352601 31 4899 106 62210 332 631716 1212686 2756245 480511 1797
+cycycy 331217 11680 564306 1340 146 230 155629 59368 172926 4630634 19 5051047 6255575 5504193 1605 75 917197 144 89 7307155 2498 5843 86 5949300 45 2062617 2021613 1439816 77747 459854 32 7450 84 36443 135 446812 1258157 3052422 649203 2303
+ascii991218 288191 12786 705286 1623 201 338 479133 168852 241329 5585522 28 3126726 6162973 4633633 2557 231 620133 525 86 6851891 4486 8533 260 4825010 133 1965883 2088031 1751200 90284 416151 57 21271 337 37794 225 831578 1728096 4864778 729995 3974
+zzy7896321 383297 15655 785716 24611 176 342 464800 168334 220835 8855289 124 6569724 6559649 5471018 2704 200 738033 447 114 9233836 4737 13923 247 6795825 139 2530006 2669110 2090170 94209 564013 57 19258 300 74171 381 1678583 1849356 4074810 871775 2633
+daerduomkch 360851 11074 679049 24554 146 243 186332 55772 162732 10723526 17 5117455 6144778 4528962 1690 41 969307 99 51 9599628 2985 5667 90 6523359 38 2793026 2820074 1708889 98393 589751 22 5629 127 42972 154 1794890 1682582 3310164 791286 2163
+memed4 1122293 25427 1756161 61182 251 403 468901 179596 509043 26459267 142 15400559 17510980 14272589 5527 219 2437917 490 152 23633204 8904 24545 255 17828124 174 6257039 6318863 5413898 165645 1656189 70 23372 431 109590 467 12040545 1697774 8591008 2541068 5956
+zhenni 4001975 30616 2395281 73507 255 395 208876 70112 722757 39849797 21 19568821 20518715 16281392 5906 98 4018808 210 178 27947957 8072 15797 125 29122931 74 8578522 8435554 7053654 238462 2248071 38 11831 246 130253 251 13480362 1909962 12103870 3024798 7347
+ihsgnef 521372 18136 1041606 24718 226 539 835416 288025 453059 13256699 28 8878523 10600276 9508158 2395 129 1252129 229 165 9612781 4016 9173 445 12457069 66 3580272 3764562 2775072 143282 747744 52 11058 430 54566 484 1811855 2319252 6520725 1260326 5307
+CosineUFO 844811 23186 1483171 22246 291 512 776032 272731 531049 17051343 28 11029509 16579517 12317195 5414 403 1784145 984 210 20463491 7645 10570 401 11906509 237 4151519 4488323 4030907 131818 1009844 113 44846 567 183731 1310 2777697 2364784 8832396 1356606 5514
+anshantby 583673 20654 1024584 36957 205 362 481182 178572 373231 14437588 23 9695213 11460532 9509303 3903 220 1730954 524 140 14176243 6448 7442 254 7653301 133 4001613 4094031 2861491 107023 953347 67 25091 357 70935 256 1960305 1788724 6340878 1297663 4834
+chenhao94 465285 16417 1056385 24551 187 282 505748 177541 267830 13824500 27 8262142 10447786 8355638 3556 236 1066463 564 130 9279591 5293 9627 264 8221219 142 3105464 3263888 2519281 94402 660824 71 26347 333 54602 238 888285 1728094 3959936 950972 4104
+Ander_cxt 535713 23975 1308422 34295 268 467 550781 195954 458526 16585195 21 15011117 20356849 18963807 4243 247 1936474 550 129 13578901 7437 12951 263 9640619 142 4562515 5126835 3259462 169934 1017081 70 34810 369 90249 439 2683596 2804309 10214630 1220665 6162
+secret_jc 509414 20833 1032817 9999999999 196 353 477082 178047 326030 14060851 26 11791076 12201587 9762270 3610 201 1163982 519 136 13772172 6557 11150 241 7088497 122 3870415 3974743 2416124 102811 766429 64 23859 312 49345 222 3809409 1621980 5306539 1101573 4434
+yefllower 430697 21880 950581 24595 148 273 202725 60891 336840 14819073 30 17365922 11104542 9443050 2283 86 1912437 167 113 11059701 4348 6588 84 14394218 47 3694032 3572748 2625333 96248 797683 45 18751 170 65251 182 8339213 1909961 6601444 1030081 3787
+brokenwing 1079596 16705 1078990 48594 171 310 153621 58923 339147 17480170 47 9145193 13132491 9934065 2560 108 1301212 181 123 14589216 3739 7868 131 15837018 77 3620494 3550946 3113246 134435 863923 41 13608 143 69905 172 1652482 1424901 6192584 1409597 3989
+xkszltl 488632 14816 797865 45701 191 297 204767 66005 282733 12915475 24 9103929 11075264 9265186 2014 78 1344746 132 92 11096063 3300 6565 69 7357900 43 3349899 3310623 2149421 111946 815466 37 7980 94 55553 157 2284180 2122175 5776130 947280 2345
+legendks 388745 26604 1112460 29506 246 430 755545 266075 381136 15634662 27 8999685 11834207 9602198 4748 401 1341965 996 198 14479612 6374 8997 386 6823843 245 3196170 3640530 3185526 123026 708951 108 45059 532 84292 334 2459707 1894868 6062020 1129659 4117
+chensqi 684242 18755 1106124 24805 342 564 796502 282444 501643 14792603 34 12202663 16775258 14134864 2825 113 1978635 297 183 16802641 4880 6850 405 8792849 54 4576597 4490821 2645024 168010 951568 127 11043 602 164880 735 3663430 2592153 8965363 1081518 5381
+ahaha 1557116 25046 1953240 61237 277 450 608131 225139 524652 24875984 191 13354044 15820676 13011725 5887 347 2039020 750 176 17767969 9919 33614 308 17257118 300 5928682 6148930 4892988 167761 1555740 94 35188 463 122618 300 2014584 1879696 9091694 1978987 5294
+jcAngel 531963 18456 1120397 36874 261 445 698217 261453 385529 13288033 22 9482225 13290187 11390251 4402 308 1339473 780 153 13139255 6554 7075 329 8780947 170 3748959 3976935 2867850 125056 764751 96 37402 462 76987 284 2271155 1955487 6764684 1048599 5373
+cheezer 328144 19357 1139114 24682 265 482 755567 266097 368443 11554324 34 7632821 11877529 9785395 4717 413 1127480 1026 235 14228028 6555 8600 403 7661063 251 3114795 3528243 2783799 102669 652959 119 44575 560 52560 324 2091470 1940369 5700312 883490 4273
+rauledly 473573 16459 887400 36983 173 417 655227 238392 245329 12924369 23 8215336 11741986 9911883 2398 80 1322793 190 143 13106114 4606 7355 337 7091442 59 3677902 3739726 2073771 113033 751064 39 9748 409 56884 165 1246729 2061551 5342105 1030745 4097
+ImaginationZ 607018 22789 1375347 24760 299 525 776032 271198 493550 15679696 27 11559931 14484392 12382296 5225 401 1622480 972 200 19328674 7220 9472 401 8802260 232 3938547 4271487 3712285 129482 929087 114 44066 545 174271 1285 3130164 2425417 8580877 1289876 5306
+Goblin911 300080 22316 1420994 29532 276 527 479154 182683 432054 17667024 148 11564367 16319729 14060264 4328 258 1509277 556 194 10125299 7571 13232 256 7953657 189 4765210 4722706 3699098 143135 711610 84 25423 353 96452 342 4000061 2364751 6321983 1544579 4968
+airsplay 478216 16419 1008165 36872 191 357 452518 169879 369027 14984924 20 8649573 10636004 8726018 3855 210 1332760 482 119 13645396 5807 7939 282 11314739 125 3762378 3940122 3270509 112428 779524 66 23072 350 67434 407 3674745 1258185 5383595 1218763 3837
+HeavnFeel 340959 19278 938132 12623 222 420 751452 278857 351148 10445082 64 10684213 21092476 19573368 3936 347 1195184 907 173 7930250 5755 12342 403 6241312 224 2744485 3034285 2395254 100595 647934 106 42818 527 56932 311 1846413 1606861 5340884 723828 4545
+zeonsgtr 547042 26519 1139159 24732 219 392 595841 232806 410746 12719690 27 10122991 12064708 10502983 3637 261 1512076 631 157 8830185 5529 13299 312 12440727 172 3567612 3655848 3048731 139243 840860 77 30782 374 76289 337 2232866 2016097 6249557 1165632 4724
+ywk248248 412747 20342 995257 48979 203 392 554891 212335 364432 12486962 184 8708067 12720739 9342514 3633 261 1385347 614 164 14652938 5934 21673 320 8217968 192 3188347 3351499 2751094 108747 913345 83 29267 397 97436 453 2517013 1637153 6202017 984445 4875
+vegetable_h 399656 19040 783136 12409 188 298 178154 55273 258240 11054537 25 11881402 16716027 16107571 1797 84 1229420 161 102 7255066 3099 6605 87 7374236 53 3443359 3253387 1997461 96265 573637 47 17933 104 67043 201 706397 1955439 5362620 850065 3335
+sy15 513364 18916 1214719 36836 201 349 466848 173977 382227 15186142 22 8069137 11187260 9037522 3500 197 1343493 484 122 13636943 5527 6820 267 13295916 119 3958250 4040576 3540431 137212 787763 69 24076 353 59690 166 1374554 1743244 5865837 1272769 4346
+rowdark 297263 18745 932704 24718 259 468 665479 232330 363255 9767039 36 7377854 10118223 9244589 4468 380 1040435 912 227 9738511 6655 7015 374 5684271 223 3020933 3351737 2572764 106841 594827 113 39458 538 57021 424 2092902 1940361 5773447 892914 4243
+swrrt_11 447661 16178 1701756 25763 186 289 237535 83413 515033 12584940 65 8179285 12369655 21457419 4974 103 1545734 180 98 11884105 16122 13181 219 8212313 61 4180943 3152282 3694545 122789 949240 47 17607 497 4634 654 9638242 1743221 50362061 1111851 9140
+ACMlzb 431740 19407 1087170 32147 203 348 466840 173439 351835 12600060 18 9612715 13325041 11075545 3519 194 1415982 499 137 15711998 6075 7864 227 7091563 105 3884590 3973462 2450646 110653 903861 59 27184 299 53531 213 13487080 1788712 5944893 1123313 4795