changeset 36:71fa409932bd

add llgrep.py, llvm_grep_translataor.py. these module requre llvm-py(and of course LLVM) to translate/execute.
author Ryoma SHINYA <shinya@firefly.cr.ie.u-ryukyu.ac.jp>
date Sun, 11 Jul 2010 22:54:39 +0900
parents 74a40ad4fa14
children 95fd780875bf
files pyrect/grep_bench.sh pyrect/llgrep.py pyrect/llvm_bench.py pyrect/llvm_grep_translator.py pyrect/llvm_translator.py pyrect/template/grep.ll pyrect/template/grep.ll.c pyrect/template/grep.ll.c~ pyrect/template/grep.ll~
diffstat 9 files changed, 1123 insertions(+), 96 deletions(-) [+]
line wrap: on
line diff
--- a/pyrect/grep_bench.sh	Sun Jul 11 22:51:44 2010 +0900
+++ b/pyrect/grep_bench.sh	Sun Jul 11 22:54:39 2010 +0900
@@ -2,29 +2,43 @@
 
 egrepout="/tmp/egrep.out"
 jitgrepout="/tmp/jitgrep.out"
-agrepout="/tmp/agrep.out"
+llgrepout="/tmp/llgrep.out"
+#agrepout="/tmp/agrep.out"
 cgrepout="/tmp/cgrep.out"
+dgrepout="/tmp/dgrep.out"
 
 echo "[jitgrep]"
 time ./jitgrep.py $@ > $jitgrepout
 #time /tmp/jitgrep $@ > $jitgrepout
 
+echo "\n[llgrep]"
+time ./llgrep.py $@ 2> /dev/null > $llgrepout
+
 echo "\n[cgrep]"
 time cgrep -E $@ > $cgrepout
 
 echo "\n[egrep]"
 time egrep    $@ > $egrepout
 
-echo "\n[agrep]"
-time agrep $@ > $agrepout
+echo "\n[dgrep (non-filter grep)]"
+time dgrep -E $@ > $dgrepout
+
+#echo "\n[agrep]"
+#time agrep $@ > $agrepout
 
 echo "\n[diff egrep jitgrep]"
 diff $egrepout $jitgrepout
 
+echo "[diff egrep llgrep]"
+diff $egrepout $llgrepout
+
 echo "[diff cgrep jitgrep]"
 diff $cgrepout $jitgrepout
 
-echo "[diff agrep jitgrep]"
-diff $agrepout $jitgrepout
+echo "[diff cgrep llgrep]"
+diff $cgrepout $llgrepout
 
-#rm -f $egrepout $jitgrepout $agrepout $cgrepout
+#echo "[diff agrep jitgrep]"
+#diff $agrepout $jitgrepout
+
+#rm -f $egrepout $jitgrepout $agrepout $cgrepout $llgrepout
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pyrect/llgrep.py	Sun Jul 11 22:54:39 2010 +0900
@@ -0,0 +1,61 @@
+#!/usr/bin/env python
+
+import sys
+import os
+import re
+import time
+from optparse import OptionParser
+from llvm_grep_translator import LLVMGREPTranslator
+from dfareg import Regexp, CallGraph
+
+def main(argv):
+    myusage = """%prog [--time] [--dump]
+                  [-O] regexp file.. [--out=file]"""
+    psr = OptionParser(usage=myusage)
+
+    redirect = ""
+    srcpath = "/tmp/jitgrep_dfa.c"
+    binpath = "/tmp/jitgrep"
+
+    psr.add_option("-O", action="store_true", dest="optimize", default=False, help="Print compile/matching time.")
+    psr.add_option("--time", action="store_true", dest="time", default=False, help="Print compile/matching time.")
+    psr.add_option("--dump", action="store_true", dest="dump", default=False, help="Dump generated grep-source.")
+    psr.add_option("--out", action="store", type="string", dest="out", default="", metavar="FILE", help="Output file.")
+
+    (opts, args) = psr.parse_args(argv)
+
+    if len(args) < 3:
+        psr.print_usage()
+        exit(0)
+
+    if opts.time : start_time = time.time()
+    reg = Regexp(args[1])
+    dfacg = CallGraph(reg.dfa)
+    grept = LLVMGREPTranslator(args[1], dfacg)
+    grept.optimize = opts.optimize
+    grept.args = args[2:]
+
+    if opts.dump:
+        grept.translate()
+        exit(0)
+
+    if (opts.time):
+        end_time = time.time()
+        print("Translation: " + str(end_time - start_time) + " Sec.")
+
+    if (opts.time): start_time = time.time()
+    grept.jitcompile()
+    if (opts.time):
+        end_time = time.time()
+        print("Compiling  : " + str(end_time - start_time) + " Sec.")
+
+    if (opts.time): redirect = "> /dev/null"
+    if (opts.out):  redirect = ">" + opts.out
+
+    if (opts.time): start_time = time.time()
+    grept.execute()
+    if (opts.time):
+        end_time = time.time()
+        print("Matching   : " + str(end_time - start_time) + " Sec.")
+
+if __name__ == '__main__': main(sys.argv)
--- a/pyrect/llvm_bench.py	Sun Jul 11 22:51:44 2010 +0900
+++ b/pyrect/llvm_bench.py	Sun Jul 11 22:54:39 2010 +0900
@@ -10,7 +10,6 @@
 myusage = "%prog [-O] [-p] [-s string] [-r regexp] [-E]"
 psr = OptionParser(usage=myusage)
 psr.add_option("-O", action="store_true", dest="optimize", default=False, help="optimimzation")
-psr.add_option("-L", action="store_true", dest="label", default=False, help="impliment with label")
 psr.add_option("-E", action="store_true", dest="execute", default=False, help="execute Module")
 psr.add_option("-p", action="store_true", dest="print_", default=False, help="print module")
 psr.add_option("-g", action="store_true", dest="debug", default=False, help="add debug stmt to module")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pyrect/llvm_grep_translator.py	Sun Jul 11 22:54:39 2010 +0900
@@ -0,0 +1,147 @@
+#!/usr/bin/env python
+
+from llvm.core import *
+from llvm.passes import *
+from llvm.ee import *
+from llvm_translator import LLVMTranslator
+from dfareg import Regexp, CallGraph
+
+class LLVMGREPTranslator(LLVMTranslator):
+    """LLVMTranslator
+    This Class can translate from DFA or NFA into LLVM-IR.
+    and also can JIT-Compile/evaluate it's self using llvm-py.
+    >>> string = 'def'
+    >>> reg = Regexp(string)
+    >>> dfacg = CallGraph(reg.dfa)
+    >>> lt = LLVMGREPTranslator(string, dfacg)
+    >>> lt.translate()
+    """
+
+    def __init__(self, regexp, cg):
+        LLVMTranslator.__init__(self, regexp, cg)
+        llfile = file("template/grep.ll")
+        self.llvm_module = Module.from_assembly(llfile)
+        self.compiled = False
+        self.string = regexp
+        self.args = []
+
+    def modify_state_name(self, state_name):
+        if self.cg.type == "DFA":
+            return self.name_hash[state_name]
+        else:
+            return state_name
+
+    def emit_driver(self):
+        self.regexp_str = self.new_str_const(self.regexp)
+        dfa = self.llvm_module.get_or_insert_function(
+            Type.function(self.int_t, (self.charptr_t,)), "DFA")
+        dfa_entry = dfa.append_basic_block("entry")
+        emit = Builder.new(dfa_entry)
+        ret = emit.call(self.llvm_module.get_function_named(self.cg.start)
+                        ,(dfa.args[0],))
+        emit.ret(ret)
+
+        main = self.llvm_module.add_function(
+            Type.function(Type.void(), (self.int_t,)), "pre_main")
+        main_entry = main.append_basic_block("entry")
+        emit = Builder.new(main_entry)
+
+        index = len(self.args)
+
+        if index == 1:
+            grep = self.llvm_module.get_function_named("llgrep")
+        else:
+            grep = self.llvm_module.get_function_named("llgrep_with_name")
+
+        for i in range(index):
+            emit.call(grep, (self.gep_first(emit, self.regexp_str),
+                             self.gep_first(emit, self.new_str_const(self.args[i]))))
+        emit.ret_void()
+
+        self.main = main
+
+    def jitcompile(self):
+        self.debug_str = self.new_str_const("state: %s, arg: %c(int %d)\n")
+        def optional_func_decl(fun):
+            #fun.calling_convertion = CC_X86_FASTCALL
+            fun.args[0].name = "index"
+
+        def func_decl(state):
+            optional_func_decl(state)
+
+        state_ref = dict()
+
+        # Create function - accept and reject (final state).
+        accept_state = self.llvm_module.add_function(
+            Type.function(self.int_t, (self.charptr_t,)), "accept")
+        optional_func_decl(accept_state)
+        reject_state = self.llvm_module.add_function(
+            Type.function(self.int_t, (self.charptr_t,)), "reject")
+        optional_func_decl(reject_state)
+
+        state_ref["accept"] = accept_state
+        state_ref["reject"] = reject_state
+
+        # add state to module, (as function or label).
+        for state in self.cg.map.iterkeys():
+            fun = self.llvm_module.add_function(
+                Type.function(self.int_t, (self.charptr_t,)), state)
+            optional_func_decl(fun)
+            state_ref[state] = fun
+
+        # emit instructions
+        emit = Builder.new(accept_state.append_basic_block("entry"))
+        emit.ret(self.const_one)
+
+        emit = Builder.new(reject_state.append_basic_block("entry"))
+        emit.ret(self.const_zero)
+
+        for state, transition in self.cg.map.iteritems():
+            cases = dict()
+            state_fun = state_ref[state]
+            emit = Builder.new(state_fun.append_basic_block("entry"))
+
+            if state in self.cg.accepts:
+                ret = emit.call(accept_state, (state_fun.args[0],))
+                emit.ret(ret)
+                continue
+
+            for case, next_states in transition.iteritems():
+                cases[self.char_const(case)] = state_ref[next_states[0]]
+
+            char = emit.load(state_fun.args[0])
+            next_ptr = emit.gep(state_fun.args[0], (self.const_one,))
+            if (self.debug): self.emit_call_printf(emit, self.debug_str, self.gep_first(emit, self.new_str_const(fun.name)), char, char)
+
+            label = 0
+            default_bb = state_fun.append_basic_block("default") #create default bb
+            builder = Builder.new(default_bb)              # default is reject.
+            ret = builder.call(reject_state, (next_ptr,))
+            builder.ret(ret)
+
+            si = emit.switch(char, default_bb, len(cases)) # create switch instruction with deafult case.
+            for case, nextFun in cases.iteritems():
+                bb = state_fun.append_basic_block("case%d" % label)   #create default bb
+                builder = Builder.new(bb)
+                ret = builder.call(nextFun, (next_ptr,))
+                builder.ret(ret)
+                si.add_case(case, bb)
+                label += 1
+
+        self.emit_driver()
+        self.mp = ModuleProvider.new(self.llvm_module)
+        if (self.optimize): self.do_optimize()
+        self.ee = ExecutionEngine.new(self.mp)
+        self.compiled = True
+
+    def execute(self):
+        if not self.compiled:
+            self.jitcompile()
+        return self.ee.run_function(self.main,
+                                    (GenericValue.int(self.int_t, 0),))
+
+def test():
+    import doctest
+    doctest.testmod()
+
+if __name__ == "__main__": test()
--- a/pyrect/llvm_translator.py	Sun Jul 11 22:51:44 2010 +0900
+++ b/pyrect/llvm_translator.py	Sun Jul 11 22:54:39 2010 +0900
@@ -19,8 +19,9 @@
     >>> isinstance(lt.execute(), llvm.ee.GenericValue)
     True
     """
+
     # define llvm core types, and const
-    int_t = Type.int()
+    int_t = Type.int(32)
     char_t = Type.int(8)
     charptr_t = Type.pointer(char_t)
     charptrptr_t = Type.pointer(charptr_t)
@@ -32,8 +33,8 @@
         Translator.__init__(self, regexp, cg)
         self.optimize = False
         self.debug = False
-        self.impl_label = False
         self.string = "ABC"
+        self.llvm_module = Module.new(self.cg.type)
         if self.cg.type == "DFA":
             self.name_hash = self.create_name_hash()
         self.compiled = False
@@ -44,10 +45,22 @@
         else:
             return state_name
 
+    def emit_driver(self):
+        main = self.llvm_module.add_function(
+            Type.function(self.int_t, (self.int_t,)), "unitmain")
+        main.args[0].name = "index"
+        main_entry = main.append_basic_block("entry")
+
+        emit = Builder.new(main_entry)
+        start = self.llvm_module.get_function_named(self.cg.start)
+        ret = emit.call(start, (main.args[0],))
+        emit.ret(ret)
+        self.main = main
+
     def _compile(self):
-        self.llvm_module = Module.new(self.cg.type)
         self.matchp_str = self.new_str_const(self.string)
         self.debug_str = self.new_str_const("state: %s, arg: %c(int %d)\n")
+
         def optional_func_decl(fun):
             fun.calling_convertion = CC_X86_FASTCALL
             fun.args[0].name = "index"
@@ -56,119 +69,73 @@
             optional_func_decl(state)
 
         state_ref = dict()
-        main = self.llvm_module.add_function(
-            Type.function(self.int_t, (self.int_t,)), "main")
-        optional_func_decl(main)
-        main_entry = main.append_basic_block("entry")
 
-        if self.impl_label:
-            accept_state = main.append_basic_block("accpet")
-            reject_state = main.append_basic_block("reject")
-            index_ptr = Builder.new(main_entry).malloc(self.int_t)
-            Builder.new(accept_state).free(index_ptr)
-            Builder.new(reject_state).free(index_ptr)
-        else:
-            # Create function - accept and reject (final state).
-            accept_state = self.llvm_module.add_function(
-                Type.function(self.int_t, (self.int_t,)), "accept")
-            optional_func_decl(accept_state)
-            reject_state = self.llvm_module.add_function(
-                Type.function(self.int_t, (self.int_t,)), "reject")
-            optional_func_decl(reject_state)
-
+        # Create function - accept and reject (final state).
+        accept_state = self.llvm_module.add_function(
+            Type.function(self.int_t, (self.int_t,)), "accept")
+        optional_func_decl(accept_state)
+        reject_state = self.llvm_module.add_function(
+            Type.function(self.int_t, (self.int_t,)), "reject")
+        optional_func_decl(reject_state)
 
         state_ref["accept"] = accept_state
         state_ref["reject"] = reject_state
 
         # add state to module, (as function or label).
-        if (self.impl_label):
-            for state in self.cg.map.iterkeys():
-                label = main.append_basic_block(state)
-                state_ref[state] = label
-        else:
-            for state in self.cg.map.iterkeys():
-                fun = self.llvm_module.add_function(
-                    Type.function(self.int_t, (self.int_t,)), state)
-                optional_func_decl(fun)
-                state_ref[state] = fun
+        for state in self.cg.map.iterkeys():
+            fun = self.llvm_module.add_function(
+                Type.function(self.int_t, (self.int_t,)), state)
+            optional_func_decl(fun)
+            state_ref[state] = fun
 
         # emit instructions
-        if (self.impl_label): emit = Builder.new(accept_state)
-        else:            emit = Builder.new(accept_state.append_basic_block("entry"))
+        emit = Builder.new(accept_state.append_basic_block("entry"))
         if self.debug: self.emit_call_printf(emit, "%s does match regexp\n", self.gep_first(emit, self.matchp_str))
         emit.ret(self.const_one)
 
-        if (self.impl_label): emit = Builder.new(reject_state)
-        else:            emit = Builder.new(reject_state.append_basic_block("entry"))
+        emit = Builder.new(reject_state.append_basic_block("entry"))
         if self.debug: self.emit_call_printf(emit, "%s does not match regexp\n", self.gep_first(emit, self.matchp_str))
         emit.ret(self.const_zero)
 
-        if (self.impl_label):
-            # emit transition instruction with jump instruction
-            emit = Builder.new(main_entry)
-            emit.store(main.args[0], index_ptr)
-            emit.branch(state_ref[self.cg.start])
+        for state, transition in self.cg.map.iteritems():
+            cases = dict()
+            if state in self.cg.accepts:
+                transition['\\0'] = ["accept"]
+            for case, next_states in transition.iteritems():
+                cases[self.char_const(case)] = state_ref[next_states[0]]
+            state_fun = state_ref[state]
+            emit = Builder.new(state_fun.append_basic_block("entry"))
+            ptr = emit.gep(self.matchp_str, (self.const_zero, state_fun.args[0]))
+            next_index = emit.add(state_fun.args[0], self.const_one)
+            char = emit.load(ptr)
+
+            if (self.debug): self.emit_call_printf(emit, self.debug_str, self.gep_first(emit, self.new_str_const(fun.name)), char, char)
 
-            for state, transition in self.cg.map.iteritems():
-                emit = Builder.new(state_ref[state])
-                index = emit.load(index_ptr)
-                ptr = emit.gep(self.matchp_str, (self.const_zero, index))
-                emit.store(emit.add(self.const_one, index), index_ptr)
-                char = emit.load(ptr)
-                si = emit.switch(char, state_ref['reject'], len(transition))
-                local_label = 0
-                if state in self.cg.accepts:
-                    transition['\\0'] = "accept"
-                for case, next_states in transition.iteritems():
-                    bb = main.append_basic_block("%s_case%d" % (state, local_label))   #create default bb
-                    emit = Builder.new(bb)
-                    emit.branch(state_ref[next_states[0]])
-                    si.add_case(self.char_const(case), bb)
-                    local_label += 1
-        else:
-            for state, transition in self.cg.map.iteritems():
-                cases = dict()
-                if state in self.cg.accepts:
-                    transition['\\0'] = ["accept"]
-                for case, next_states in transition.iteritems():
-                    cases[self.char_const(case)] = state_ref[next_states[0]]
-                state_fun = state_ref[state]
-                emit = Builder.new(state_fun.append_basic_block("entry"))
-                ptr = emit.gep(self.matchp_str, (self.const_zero, state_fun.args[0]))
-                next_index = emit.add(state_fun.args[0], self.const_one)
-                char = emit.load(ptr)
+            label = 0
+            default_bb = state_fun.append_basic_block("default") #create default bb
+            builder = Builder.new(default_bb)              # default is reject.
+            ret = builder.call(reject_state, (next_index,))
+            builder.ret(ret)
 
-                if (self.debug): self.emit_call_printf(emit, self.debug_str, self.gep_first(emit, self.new_str_const(fun.name)), char, char)
-
-                label = 0
-                default_bb = state_fun.append_basic_block("default") #create default bb
-                builder = Builder.new(default_bb)              # default is reject.
-                ret = builder.call(reject_state, (next_index,))
+            si = emit.switch(char, default_bb, len(cases)) # create switch instruction with deafult case.
+            for case, nextFun in cases.iteritems():
+                bb = state_fun.append_basic_block("case%d" % label)   #create default bb
+                builder = Builder.new(bb)
+                ret = builder.call(nextFun, (next_index,))
                 builder.ret(ret)
-
-                si = emit.switch(char, default_bb, len(cases)) # create switch instruction with deafult case.
-                for case, nextFun in cases.iteritems():
-                    bb = state_fun.append_basic_block("case%d" % label)   #create default bb
-                    builder = Builder.new(bb)
-                    ret = builder.call(nextFun, (next_index,))
-                    builder.ret(ret)
-                    si.add_case(case, bb)
-                    label += 1
-            emit = Builder.new(main_entry)
-            ret = emit.call(state_ref[self.cg.start], (main.args[0],))
-            emit.ret(ret)
+                si.add_case(case, bb)
+                label += 1
 
         self.mp = ModuleProvider.new(self.llvm_module)
         if (self.optimize): self.do_optimize()
         self.ee = ExecutionEngine.new(self.mp)
-        self.main = main
+        self.emit_driver()
         self.compiled = True
 
     def emit_from_callgraph(self):
         if not self.compiled:
             self._compile()
         self.emit(str(self.llvm_module))
-
     def get_execution_engine(self):
         if not self.compiled:
             self._compile()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pyrect/template/grep.ll	Sun Jul 11 22:54:39 2010 +0900
@@ -0,0 +1,377 @@
+; ModuleID = 'template/grep.ll.c'
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+target triple = "i386-apple-darwin9"
+	%struct.FILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 }
+	%struct.__sFILEX = type opaque
+	%struct.__sbuf = type { i8*, i32 }
+@"\01LC" = internal constant [4 x i8] c"%s:\00"		; <[4 x i8]*> [#uses=1]
+@"\01LC1" = internal constant [2 x i8] c"r\00"		; <[2 x i8]*> [#uses=1]
+@__stderrp = external global %struct.FILE*		; <%struct.FILE**> [#uses=4]
+@"\01LC2" = internal constant [15 x i8] c"can't open %s:\00"		; <[15 x i8]*> [#uses=1]
+@readbuf = common global [1048576 x i8] zeroinitializer, align 32		; <[1048576 x i8]*> [#uses=1]
+@"\01LC3" = internal constant [30 x i8] c"usage: grep regexp [file ...]\00"		; <[30 x i8]*> [#uses=1]
+@__stdinp = external global %struct.FILE*		; <%struct.FILE**> [#uses=1]
+
+define i32 @match(i8* %regexp, i8* %text) nounwind  {
+entry:
+	%regexp_addr = alloca i8*		; <i8**> [#uses=2]
+	%text_addr = alloca i8*		; <i8**> [#uses=6]
+	%retval = alloca i32		; <i32*> [#uses=2]
+	alloca i32		; <i32*>:0 [#uses=4]
+	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
+	store i8* %regexp, i8** %regexp_addr
+	store i8* %text, i8** %text_addr
+	load i8** %regexp_addr, align 4		; <i8*>:1 [#uses=1]
+	getelementptr i8* %1, i32 0		; <i8*>:2 [#uses=1]
+	load i8* %2, align 1		; <i8>:3 [#uses=1]
+	icmp eq i8 %3, 94		; <i1>:4 [#uses=1]
+	zext i1 %4 to i8		; <i8>:5 [#uses=1]
+	%toBool = icmp ne i8 %5, 0		; <i1> [#uses=1]
+	br i1 %toBool, label %bb, label %bb1
+
+bb:		; preds = %entry
+	load i8** %text_addr, align 4		; <i8*>:6 [#uses=1]
+	call i32 @DFA( i8* %6 ) nounwind 		; <i32>:7 [#uses=1]
+	store i32 %7, i32* %0, align 4
+	br label %bb7
+
+bb1:		; preds = %bb4, %entry
+	load i8** %text_addr, align 4		; <i8*>:8 [#uses=1]
+	call i32 @DFA( i8* %8 ) nounwind 		; <i32>:9 [#uses=1]
+	icmp ne i32 %9, 0		; <i1>:10 [#uses=1]
+	zext i1 %10 to i8		; <i8>:11 [#uses=1]
+	%toBool2 = icmp ne i8 %11, 0		; <i1> [#uses=1]
+	br i1 %toBool2, label %bb3, label %bb4
+
+bb3:		; preds = %bb1
+	store i32 1, i32* %0, align 4
+	br label %bb7
+
+bb4:		; preds = %bb1
+	load i8** %text_addr, align 4		; <i8*>:12 [#uses=1]
+	load i8* %12, align 1		; <i8>:13 [#uses=1]
+	icmp ne i8 %13, 0		; <i1>:14 [#uses=1]
+	zext i1 %14 to i8		; <i8>:15 [#uses=1]
+	load i8** %text_addr, align 4		; <i8*>:16 [#uses=1]
+	getelementptr i8* %16, i64 1		; <i8*>:17 [#uses=1]
+	store i8* %17, i8** %text_addr, align 4
+	%toBool5 = icmp ne i8 %15, 0		; <i1> [#uses=1]
+	br i1 %toBool5, label %bb1, label %bb6
+
+bb6:		; preds = %bb4
+	store i32 0, i32* %0, align 4
+	br label %bb7
+
+bb7:		; preds = %bb6, %bb3, %bb
+	load i32* %0, align 4		; <i32>:18 [#uses=1]
+	store i32 %18, i32* %retval, align 4
+	br label %return
+
+return:		; preds = %bb7
+	%retval8 = load i32* %retval		; <i32> [#uses=1]
+	ret i32 %retval8
+}
+
+declare i32 @DFA(i8*)
+
+define void @grep(i8* %regexp, %struct.FILE* %f, i8* %name) nounwind  {
+entry:
+	%regexp_addr = alloca i8*		; <i8**> [#uses=2]
+	%f_addr = alloca %struct.FILE*		; <%struct.FILE**> [#uses=2]
+	%name_addr = alloca i8*		; <i8**> [#uses=3]
+	%buf = alloca [1024 x i8]		; <[1024 x i8]*> [#uses=6]
+	%n = alloca i32		; <i32*> [#uses=4]
+	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
+	store i8* %regexp, i8** %regexp_addr
+	store %struct.FILE* %f, %struct.FILE** %f_addr
+	store i8* %name, i8** %name_addr
+	br label %bb13
+
+bb:		; preds = %bb13
+	%buf1 = bitcast [1024 x i8]* %buf to i8*		; <i8*> [#uses=1]
+	call i32 @strlen( i8* %buf1 ) nounwind readonly 		; <i32>:0 [#uses=1]
+	store i32 %0, i32* %n, align 4
+	load i32* %n, align 4		; <i32>:1 [#uses=1]
+	icmp sgt i32 %1, 0		; <i1>:2 [#uses=1]
+	zext i1 %2 to i8		; <i8>:3 [#uses=1]
+	%toBool = icmp ne i8 %3, 0		; <i1> [#uses=1]
+	br i1 %toBool, label %bb2, label %bb5
+
+bb2:		; preds = %bb
+	load i32* %n, align 4		; <i32>:4 [#uses=1]
+	sub i32 %4, 1		; <i32>:5 [#uses=1]
+	getelementptr [1024 x i8]* %buf, i32 0, i32 %5		; <i8*>:6 [#uses=1]
+	load i8* %6, align 1		; <i8>:7 [#uses=1]
+	icmp eq i8 %7, 10		; <i1>:8 [#uses=1]
+	zext i1 %8 to i8		; <i8>:9 [#uses=1]
+	%toBool3 = icmp ne i8 %9, 0		; <i1> [#uses=1]
+	br i1 %toBool3, label %bb4, label %bb5
+
+bb4:		; preds = %bb2
+	load i32* %n, align 4		; <i32>:10 [#uses=1]
+	sub i32 %10, 1		; <i32>:11 [#uses=1]
+	getelementptr [1024 x i8]* %buf, i32 0, i32 %11		; <i8*>:12 [#uses=1]
+	store i8 0, i8* %12, align 1
+	br label %bb5
+
+bb5:		; preds = %bb4, %bb2, %bb
+	load i8** %regexp_addr, align 4		; <i8*>:13 [#uses=1]
+	%buf6 = bitcast [1024 x i8]* %buf to i8*		; <i8*> [#uses=1]
+	call i32 @match( i8* %13, i8* %buf6 ) nounwind 		; <i32>:14 [#uses=1]
+	icmp ne i32 %14, 0		; <i1>:15 [#uses=1]
+	zext i1 %15 to i8		; <i8>:16 [#uses=1]
+	%toBool7 = icmp ne i8 %16, 0		; <i1> [#uses=1]
+	br i1 %toBool7, label %bb8, label %bb13
+
+bb8:		; preds = %bb5
+	load i8** %name_addr, align 4		; <i8*>:17 [#uses=1]
+	icmp ne i8* %17, null		; <i1>:18 [#uses=1]
+	zext i1 %18 to i8		; <i8>:19 [#uses=1]
+	%toBool9 = icmp ne i8 %19, 0		; <i1> [#uses=1]
+	br i1 %toBool9, label %bb10, label %bb11
+
+bb10:		; preds = %bb8
+	load i8** %name_addr, align 4		; <i8*>:20 [#uses=1]
+	call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @"\01LC", i32 0, i32 0), i8* %20 ) nounwind 		; <i32>:21 [#uses=0]
+	br label %bb11
+
+bb11:		; preds = %bb10, %bb8
+	%buf12 = bitcast [1024 x i8]* %buf to i8*		; <i8*> [#uses=1]
+	call i32 @puts( i8* %buf12 ) nounwind 		; <i32>:22 [#uses=0]
+	br label %bb13
+
+bb13:		; preds = %bb11, %bb5, %entry
+	%buf14 = bitcast [1024 x i8]* %buf to i8*		; <i8*> [#uses=1]
+	load %struct.FILE** %f_addr, align 4		; <%struct.FILE*>:23 [#uses=1]
+	call i8* @fgets( i8* %buf14, i32 1024, %struct.FILE* %23 ) nounwind 		; <i8*>:24 [#uses=1]
+	icmp ne i8* %24, null		; <i1>:25 [#uses=1]
+	zext i1 %25 to i8		; <i8>:26 [#uses=1]
+	%toBool15 = icmp ne i8 %26, 0		; <i1> [#uses=1]
+	br i1 %toBool15, label %bb, label %bb16
+
+bb16:		; preds = %bb13
+	br label %return
+
+return:		; preds = %bb16
+	ret void
+}
+
+declare i32 @strlen(i8*) nounwind readonly 
+
+declare i32 @printf(i8*, ...) nounwind 
+
+declare i32 @puts(i8*)
+
+declare i8* @fgets(i8*, i32, %struct.FILE*)
+
+define void @llgrep(i8* %regexp, i8* %filename) nounwind  {
+entry:
+	%regexp_addr = alloca i8*		; <i8**> [#uses=2]
+	%filename_addr = alloca i8*		; <i8**> [#uses=3]
+	%f = alloca %struct.FILE*		; <%struct.FILE**> [#uses=5]
+	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
+	store i8* %regexp, i8** %regexp_addr
+	store i8* %filename, i8** %filename_addr
+	load i8** %filename_addr, align 4		; <i8*>:0 [#uses=1]
+	call %struct.FILE* @fopen( i8* %0, i8* getelementptr ([2 x i8]* @"\01LC1", i32 0, i32 0) ) nounwind 		; <%struct.FILE*>:1 [#uses=1]
+	store %struct.FILE* %1, %struct.FILE** %f, align 4
+	load %struct.FILE** %f, align 4		; <%struct.FILE*>:2 [#uses=1]
+	icmp eq %struct.FILE* %2, null		; <i1>:3 [#uses=1]
+	zext i1 %3 to i8		; <i8>:4 [#uses=1]
+	%toBool = icmp ne i8 %4, 0		; <i1> [#uses=1]
+	br i1 %toBool, label %bb, label %bb1
+
+bb:		; preds = %entry
+	load %struct.FILE** @__stderrp, align 4		; <%struct.FILE*>:5 [#uses=1]
+	load i8** %filename_addr, align 4		; <i8*>:6 [#uses=1]
+	call i32 (%struct.FILE*, i8*, ...)* @fprintf( %struct.FILE* %5, i8* getelementptr ([15 x i8]* @"\01LC2", i32 0, i32 0), i8* %6 ) nounwind 		; <i32>:7 [#uses=0]
+	br label %bb1
+
+bb1:		; preds = %bb, %entry
+	load %struct.FILE** %f, align 4		; <%struct.FILE*>:8 [#uses=1]
+	call i32 @setvbuf( %struct.FILE* %8, i8* getelementptr ([1048576 x i8]* @readbuf, i32 0, i32 0), i32 0, i32 1048576 ) nounwind 		; <i32>:9 [#uses=0]
+	load i8** %regexp_addr, align 4		; <i8*>:10 [#uses=1]
+	load %struct.FILE** %f, align 4		; <%struct.FILE*>:11 [#uses=1]
+	call void @grep( i8* %10, %struct.FILE* %11, i8* null ) nounwind 
+	load %struct.FILE** %f, align 4		; <%struct.FILE*>:12 [#uses=1]
+	call i32 @fclose( %struct.FILE* %12 ) nounwind 		; <i32>:13 [#uses=0]
+	br label %return
+
+return:		; preds = %bb1
+	ret void
+}
+
+declare %struct.FILE* @fopen(i8*, i8*)
+
+declare i32 @fprintf(%struct.FILE*, i8*, ...) nounwind 
+
+declare i32 @setvbuf(%struct.FILE*, i8*, i32, i32)
+
+declare i32 @fclose(%struct.FILE*)
+
+define void @llgrep_with_name(i8* %regexp, i8* %filename) nounwind  {
+entry:
+	%regexp_addr = alloca i8*		; <i8**> [#uses=2]
+	%filename_addr = alloca i8*		; <i8**> [#uses=4]
+	%f = alloca %struct.FILE*		; <%struct.FILE**> [#uses=5]
+	%nmatch = alloca i32		; <i32*> [#uses=1]
+	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
+	store i8* %regexp, i8** %regexp_addr
+	store i8* %filename, i8** %filename_addr
+	store i32 0, i32* %nmatch, align 4
+	load i8** %filename_addr, align 4		; <i8*>:0 [#uses=1]
+	call %struct.FILE* @fopen( i8* %0, i8* getelementptr ([2 x i8]* @"\01LC1", i32 0, i32 0) ) nounwind 		; <%struct.FILE*>:1 [#uses=1]
+	store %struct.FILE* %1, %struct.FILE** %f, align 4
+	load %struct.FILE** %f, align 4		; <%struct.FILE*>:2 [#uses=1]
+	icmp eq %struct.FILE* %2, null		; <i1>:3 [#uses=1]
+	zext i1 %3 to i8		; <i8>:4 [#uses=1]
+	%toBool = icmp ne i8 %4, 0		; <i1> [#uses=1]
+	br i1 %toBool, label %bb, label %bb1
+
+bb:		; preds = %entry
+	load %struct.FILE** @__stderrp, align 4		; <%struct.FILE*>:5 [#uses=1]
+	load i8** %filename_addr, align 4		; <i8*>:6 [#uses=1]
+	call i32 (%struct.FILE*, i8*, ...)* @fprintf( %struct.FILE* %5, i8* getelementptr ([15 x i8]* @"\01LC2", i32 0, i32 0), i8* %6 ) nounwind 		; <i32>:7 [#uses=0]
+	br label %bb1
+
+bb1:		; preds = %bb, %entry
+	load %struct.FILE** %f, align 4		; <%struct.FILE*>:8 [#uses=1]
+	call i32 @setvbuf( %struct.FILE* %8, i8* getelementptr ([1048576 x i8]* @readbuf, i32 0, i32 0), i32 0, i32 1048576 ) nounwind 		; <i32>:9 [#uses=0]
+	load i8** %regexp_addr, align 4		; <i8*>:10 [#uses=1]
+	load %struct.FILE** %f, align 4		; <%struct.FILE*>:11 [#uses=1]
+	load i8** %filename_addr, align 4		; <i8*>:12 [#uses=1]
+	call void @grep( i8* %10, %struct.FILE* %11, i8* %12 ) nounwind 
+	load %struct.FILE** %f, align 4		; <%struct.FILE*>:13 [#uses=1]
+	call i32 @fclose( %struct.FILE* %13 ) nounwind 		; <i32>:14 [#uses=0]
+	br label %return
+
+return:		; preds = %bb1
+	ret void
+}
+
+define i32 @main(i32 %argc, i8** %argv) nounwind  {
+entry:
+	%argc_addr = alloca i32		; <i32*> [#uses=5]
+	%argv_addr = alloca i8**		; <i8***> [#uses=6]
+	%retval = alloca i32		; <i32*> [#uses=2]
+	%f = alloca %struct.FILE*		; <%struct.FILE**> [#uses=5]
+	%i = alloca i32		; <i32*> [#uses=7]
+	alloca i32		; <i32*>:0 [#uses=2]
+	%iftmp.5 = alloca i8*		; <i8**> [#uses=3]
+	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
+	store i32 %argc, i32* %argc_addr
+	store i8** %argv, i8*** %argv_addr
+	load i32* %argc_addr, align 4		; <i32>:1 [#uses=1]
+	icmp sle i32 %1, 1		; <i1>:2 [#uses=1]
+	zext i1 %2 to i8		; <i8>:3 [#uses=1]
+	%toBool = icmp ne i8 %3, 0		; <i1> [#uses=1]
+	br i1 %toBool, label %bb, label %bb1
+
+bb:		; preds = %entry
+	load %struct.FILE** @__stderrp, align 4		; <%struct.FILE*>:4 [#uses=1]
+	bitcast %struct.FILE* %4 to i8*		; <i8*>:5 [#uses=1]
+	call i32 @"\01_fwrite$UNIX2003"( i8* getelementptr ([30 x i8]* @"\01LC3", i32 0, i32 0), i32 1, i32 29, i8* %5 ) nounwind 		; <i32>:6 [#uses=0]
+	call void @exit( i32 0 ) noreturn nounwind 
+	unreachable
+
+bb1:		; preds = %entry
+	load i32* %argc_addr, align 4		; <i32>:7 [#uses=1]
+	icmp eq i32 %7, 2		; <i1>:8 [#uses=1]
+	zext i1 %8 to i8		; <i8>:9 [#uses=1]
+	%toBool2 = icmp ne i8 %9, 0		; <i1> [#uses=1]
+	br i1 %toBool2, label %bb3, label %bb4
+
+bb3:		; preds = %bb1
+	load %struct.FILE** @__stdinp, align 4		; <%struct.FILE*>:10 [#uses=1]
+	load i8*** %argv_addr, align 4		; <i8**>:11 [#uses=1]
+	getelementptr i8** %11, i32 1		; <i8**>:12 [#uses=1]
+	load i8** %12, align 4		; <i8*>:13 [#uses=1]
+	call void @grep( i8* %13, %struct.FILE* %10, i8* null ) nounwind 
+	br label %bb16
+
+bb4:		; preds = %bb1
+	store i32 2, i32* %i, align 4
+	br label %bb14
+
+bb5:		; preds = %bb14
+	load i8*** %argv_addr, align 4		; <i8**>:14 [#uses=1]
+	load i32* %i, align 4		; <i32>:15 [#uses=1]
+	getelementptr i8** %14, i32 %15		; <i8**>:16 [#uses=1]
+	load i8** %16, align 4		; <i8*>:17 [#uses=1]
+	call %struct.FILE* @fopen( i8* %17, i8* getelementptr ([2 x i8]* @"\01LC1", i32 0, i32 0) ) nounwind 		; <%struct.FILE*>:18 [#uses=1]
+	store %struct.FILE* %18, %struct.FILE** %f, align 4
+	load %struct.FILE** %f, align 4		; <%struct.FILE*>:19 [#uses=1]
+	icmp eq %struct.FILE* %19, null		; <i1>:20 [#uses=1]
+	zext i1 %20 to i8		; <i8>:21 [#uses=1]
+	%toBool6 = icmp ne i8 %21, 0		; <i1> [#uses=1]
+	br i1 %toBool6, label %bb7, label %bb8
+
+bb7:		; preds = %bb5
+	load i8*** %argv_addr, align 4		; <i8**>:22 [#uses=1]
+	load i32* %i, align 4		; <i32>:23 [#uses=1]
+	getelementptr i8** %22, i32 %23		; <i8**>:24 [#uses=1]
+	load i8** %24, align 4		; <i8*>:25 [#uses=1]
+	load %struct.FILE** @__stderrp, align 4		; <%struct.FILE*>:26 [#uses=1]
+	call i32 (%struct.FILE*, i8*, ...)* @fprintf( %struct.FILE* %26, i8* getelementptr ([15 x i8]* @"\01LC2", i32 0, i32 0), i8* %25 ) nounwind 		; <i32>:27 [#uses=0]
+	br label %bb13
+
+bb8:		; preds = %bb5
+	load %struct.FILE** %f, align 4		; <%struct.FILE*>:28 [#uses=1]
+	call i32 @setvbuf( %struct.FILE* %28, i8* getelementptr ([1048576 x i8]* @readbuf, i32 0, i32 0), i32 0, i32 1048576 ) nounwind 		; <i32>:29 [#uses=0]
+	load i32* %argc_addr, align 4		; <i32>:30 [#uses=1]
+	icmp sgt i32 %30, 3		; <i1>:31 [#uses=1]
+	zext i1 %31 to i8		; <i8>:32 [#uses=1]
+	%toBool9 = icmp ne i8 %32, 0		; <i1> [#uses=1]
+	br i1 %toBool9, label %bb10, label %bb11
+
+bb10:		; preds = %bb8
+	load i8*** %argv_addr, align 4		; <i8**>:33 [#uses=1]
+	load i32* %i, align 4		; <i32>:34 [#uses=1]
+	getelementptr i8** %33, i32 %34		; <i8**>:35 [#uses=1]
+	load i8** %35, align 4		; <i8*>:36 [#uses=1]
+	store i8* %36, i8** %iftmp.5, align 4
+	br label %bb12
+
+bb11:		; preds = %bb8
+	store i8* null, i8** %iftmp.5, align 4
+	br label %bb12
+
+bb12:		; preds = %bb11, %bb10
+	load i8*** %argv_addr, align 4		; <i8**>:37 [#uses=1]
+	getelementptr i8** %37, i32 1		; <i8**>:38 [#uses=1]
+	load i8** %38, align 4		; <i8*>:39 [#uses=1]
+	load %struct.FILE** %f, align 4		; <%struct.FILE*>:40 [#uses=1]
+	load i8** %iftmp.5, align 4		; <i8*>:41 [#uses=1]
+	call void @grep( i8* %39, %struct.FILE* %40, i8* %41 ) nounwind 
+	load %struct.FILE** %f, align 4		; <%struct.FILE*>:42 [#uses=1]
+	call i32 @fclose( %struct.FILE* %42 ) nounwind 		; <i32>:43 [#uses=0]
+	br label %bb13
+
+bb13:		; preds = %bb12, %bb7
+	load i32* %i, align 4		; <i32>:44 [#uses=1]
+	add i32 %44, 1		; <i32>:45 [#uses=1]
+	store i32 %45, i32* %i, align 4
+	br label %bb14
+
+bb14:		; preds = %bb13, %bb4
+	load i32* %i, align 4		; <i32>:46 [#uses=1]
+	load i32* %argc_addr, align 4		; <i32>:47 [#uses=1]
+	icmp slt i32 %46, %47		; <i1>:48 [#uses=1]
+	zext i1 %48 to i8		; <i8>:49 [#uses=1]
+	%toBool15 = icmp ne i8 %49, 0		; <i1> [#uses=1]
+	br i1 %toBool15, label %bb5, label %bb16
+
+bb16:		; preds = %bb14, %bb3
+	store i32 0, i32* %0, align 4
+	load i32* %0, align 4		; <i32>:50 [#uses=1]
+	store i32 %50, i32* %retval, align 4
+	br label %return
+
+return:		; preds = %bb16
+	%retval17 = load i32* %retval		; <i32> [#uses=1]
+	ret i32 %retval17
+}
+
+declare i32 @"\01_fwrite$UNIX2003"(i8*, i32, i32, i8*)
+
+declare void @exit(i32) noreturn nounwind 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pyrect/template/grep.ll.c	Sun Jul 11 22:54:39 2010 +0900
@@ -0,0 +1,89 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define LINEBUFSIZE 1024
+#define READBUFSIZE 1024*1024
+char readbuf[READBUFSIZE];
+
+extern int DFA(char* text);
+
+int match(char *regexp, char *text) {
+  if (regexp[0] == '^')
+    return DFA(text);
+  do {
+    if (DFA(text))
+      return 1;
+  } while (*text++ != '\0');
+    return 0;
+}
+
+void grep(char *regexp, FILE *f, char *name) {
+  int n;
+  char buf[LINEBUFSIZE];
+  while (fgets(buf, sizeof buf, f) != NULL) {
+    n = strlen(buf);
+    if (n > 0 && buf[n-1] == '\n')
+      buf[n-1] = '\0';
+    if (match(regexp, buf)) {
+      if (name != NULL)
+        printf("%s:", name);
+      printf("%s\n", buf);
+    }
+  }
+  return;
+}
+
+void llgrep(char *regexp, char* filename) {
+  FILE *f;
+  f = fopen(filename, "r");
+  if (f == NULL) {
+    fprintf(stderr, "can't open %s:", filename);
+  }
+  if (READBUFSIZE > 0)
+    setvbuf(f, readbuf, _IOFBF, READBUFSIZE);
+  grep(regexp, f, NULL);
+  fclose(f);
+  return;
+}
+
+void llgrep_with_name(char *regexp, char* filename) {
+  int nmatch = 0;
+  FILE *f;
+  f = fopen(filename, "r");
+  if (f == NULL) {
+    fprintf(stderr, "can't open %s:", filename);
+  }
+  if (READBUFSIZE > 0)
+    setvbuf(f, readbuf, _IOFBF, READBUFSIZE);
+  grep(regexp, f, filename);
+  fclose(f);
+  return;
+}
+
+int main(int argc, char* argv[]) {
+  int i;
+  FILE *f;
+
+  if (argc < 2) {
+    fprintf(stderr, "usage: grep regexp [file ...]");
+    exit(0);
+  }
+  if (argc == 2) {
+    grep(argv[1], stdin, NULL);
+  } else {
+    for (i = 2; i < argc; i++) {
+      f = fopen(argv[i], "r");
+      if (f == NULL) {
+        fprintf(stderr, "can't open %s:", argv[i]);
+        continue;
+      }
+      if (READBUFSIZE > 0)
+        setvbuf(f, readbuf, _IOFBF, READBUFSIZE);
+      grep(argv[1], f, argc > 3 ? argv[i] : NULL);
+      fclose(f);
+    }
+  }
+
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pyrect/template/grep.ll.c~	Sun Jul 11 22:54:39 2010 +0900
@@ -0,0 +1,89 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define LINEBUFSIZE 1024
+#define READBUFSIZE 1024*1024
+char readbuf[READBUFSIZE];
+
+extern int DFA(char* text);
+
+int match(char *regexp, char *text) {
+  if (regexp[0] == '^')
+    return DFA(text);
+  do {
+    if (DFA(text))
+      return 1;
+  } while (text++ != '\0');
+    return 0;
+}
+
+void grep(char *regexp, FILE *f, char *name) {
+  int n;
+  char buf[LINEBUFSIZE];
+  while (fgets(buf, sizeof buf, f) != NULL) {
+    n = strlen(buf);
+    if (n > 0 && buf[n-1] == '\n')
+      buf[n-1] = '\0';
+    if (match(regexp, buf)) {
+      if (name != NULL)
+        printf("%s:", name);
+      printf("%s\n", buf);
+    }
+  }
+  return;
+}
+
+void llgrep(char *regexp, char* filename) {
+  FILE *f;
+  f = fopen(filename, "r");
+  if (f == NULL) {
+    fprintf(stderr, "can't open %s:", filename);
+  }
+  if (READBUFSIZE > 0)
+    setvbuf(f, readbuf, _IOFBF, READBUFSIZE);
+  grep(regexp, f, NULL);
+  fclose(f);
+  return;
+}
+
+void llgrep_with_name(char *regexp, char* filename) {
+  int nmatch = 0;
+  FILE *f;
+  f = fopen(filename, "r");
+  if (f == NULL) {
+    fprintf(stderr, "can't open %s:", filename);
+  }
+  if (READBUFSIZE > 0)
+    setvbuf(f, readbuf, _IOFBF, READBUFSIZE);
+  grep(regexp, f, filename);
+  fclose(f);
+  return;
+}
+
+int main(int argc, char* argv[]) {
+  int i;
+  FILE *f;
+
+  if (argc < 2) {
+    fprintf(stderr, "usage: grep regexp [file ...]");
+    exit(0);
+  }
+  if (argc == 2) {
+    grep(argv[1], stdin, NULL);
+  } else {
+    for (i = 2; i < argc; i++) {
+      f = fopen(argv[i], "r");
+      if (f == NULL) {
+        fprintf(stderr, "can't open %s:", argv[i]);
+        continue;
+      }
+      if (READBUFSIZE > 0)
+        setvbuf(f, readbuf, _IOFBF, READBUFSIZE);
+      grep(argv[1], f, argc > 3 ? argv[i] : NULL);
+      fclose(f);
+    }
+  }
+
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pyrect/template/grep.ll~	Sun Jul 11 22:54:39 2010 +0900
@@ -0,0 +1,284 @@
+; ModuleID = 'template/grep.ll.c'
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+target triple = "i386-apple-darwin9"
+	%struct.FILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 }
+	%struct.__sFILEX = type opaque
+	%struct.__sbuf = type { i8*, i32 }
+@"\01LC" = internal constant [4 x i8] c"%s:\00"		; <[4 x i8]*> [#uses=1]
+@__stderrp = external global %struct.FILE*		; <%struct.FILE**> [#uses=2]
+@"\01LC1" = internal constant [30 x i8] c"usage: grep regexp [file ...]\00"		; <[30 x i8]*> [#uses=1]
+@__stdinp = external global %struct.FILE*		; <%struct.FILE**> [#uses=1]
+@"\01LC2" = internal constant [2 x i8] c"r\00"		; <[2 x i8]*> [#uses=1]
+@"\01LC3" = internal constant [15 x i8] c"can't open %s:\00"		; <[15 x i8]*> [#uses=1]
+@readbuf = common global [1048576 x i8] zeroinitializer, align 32		; <[1048576 x i8]*> [#uses=1]
+
+define i32 @match(i8* %regexp, i8* %text) nounwind  {
+entry:
+	%regexp_addr = alloca i8*		; <i8**> [#uses=1]
+	%text_addr = alloca i8*		; <i8**> [#uses=1]
+	%retval = alloca i32		; <i32*> [#uses=2]
+	alloca i32		; <i32*>:0 [#uses=2]
+	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
+	store i8* %regexp, i8** %regexp_addr
+	store i8* %text, i8** %text_addr
+	store i32 1, i32* %0, align 4
+	load i32* %0, align 4		; <i32>:1 [#uses=1]
+	store i32 %1, i32* %retval, align 4
+	br label %return
+
+return:		; preds = %entry
+	%retval1 = load i32* %retval		; <i32> [#uses=1]
+	ret i32 %retval1
+}
+
+define i32 @grep(i8* %regexp, %struct.FILE* %f, i8* %name) nounwind  {
+entry:
+	%regexp_addr = alloca i8*		; <i8**> [#uses=2]
+	%f_addr = alloca %struct.FILE*		; <%struct.FILE**> [#uses=2]
+	%name_addr = alloca i8*		; <i8**> [#uses=3]
+	%retval = alloca i32		; <i32*> [#uses=2]
+	%buf = alloca [1024 x i8]		; <[1024 x i8]*> [#uses=6]
+	%nmatch = alloca i32		; <i32*> [#uses=4]
+	%n = alloca i32		; <i32*> [#uses=4]
+	alloca i32		; <i32*>:0 [#uses=2]
+	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
+	store i8* %regexp, i8** %regexp_addr
+	store %struct.FILE* %f, %struct.FILE** %f_addr
+	store i8* %name, i8** %name_addr
+	store i32 0, i32* %nmatch, align 4
+	br label %bb13
+
+bb:		; preds = %bb13
+	%buf1 = bitcast [1024 x i8]* %buf to i8*		; <i8*> [#uses=1]
+	call i32 @strlen( i8* %buf1 ) nounwind readonly 		; <i32>:1 [#uses=1]
+	store i32 %1, i32* %n, align 4
+	load i32* %n, align 4		; <i32>:2 [#uses=1]
+	icmp sgt i32 %2, 0		; <i1>:3 [#uses=1]
+	zext i1 %3 to i8		; <i8>:4 [#uses=1]
+	%toBool = icmp ne i8 %4, 0		; <i1> [#uses=1]
+	br i1 %toBool, label %bb2, label %bb5
+
+bb2:		; preds = %bb
+	load i32* %n, align 4		; <i32>:5 [#uses=1]
+	sub i32 %5, 1		; <i32>:6 [#uses=1]
+	getelementptr [1024 x i8]* %buf, i32 0, i32 %6		; <i8*>:7 [#uses=1]
+	load i8* %7, align 1		; <i8>:8 [#uses=1]
+	icmp eq i8 %8, 10		; <i1>:9 [#uses=1]
+	zext i1 %9 to i8		; <i8>:10 [#uses=1]
+	%toBool3 = icmp ne i8 %10, 0		; <i1> [#uses=1]
+	br i1 %toBool3, label %bb4, label %bb5
+
+bb4:		; preds = %bb2
+	load i32* %n, align 4		; <i32>:11 [#uses=1]
+	sub i32 %11, 1		; <i32>:12 [#uses=1]
+	getelementptr [1024 x i8]* %buf, i32 0, i32 %12		; <i8*>:13 [#uses=1]
+	store i8 0, i8* %13, align 1
+	br label %bb5
+
+bb5:		; preds = %bb4, %bb2, %bb
+	load i8** %regexp_addr, align 4		; <i8*>:14 [#uses=1]
+	%buf6 = bitcast [1024 x i8]* %buf to i8*		; <i8*> [#uses=1]
+	call i32 @match( i8* %14, i8* %buf6 ) nounwind 		; <i32>:15 [#uses=1]
+	icmp ne i32 %15, 0		; <i1>:16 [#uses=1]
+	zext i1 %16 to i8		; <i8>:17 [#uses=1]
+	%toBool7 = icmp ne i8 %17, 0		; <i1> [#uses=1]
+	br i1 %toBool7, label %bb8, label %bb13
+
+bb8:		; preds = %bb5
+	load i32* %nmatch, align 4		; <i32>:18 [#uses=1]
+	add i32 %18, 1		; <i32>:19 [#uses=1]
+	store i32 %19, i32* %nmatch, align 4
+	load i8** %name_addr, align 4		; <i8*>:20 [#uses=1]
+	icmp ne i8* %20, null		; <i1>:21 [#uses=1]
+	zext i1 %21 to i8		; <i8>:22 [#uses=1]
+	%toBool9 = icmp ne i8 %22, 0		; <i1> [#uses=1]
+	br i1 %toBool9, label %bb10, label %bb11
+
+bb10:		; preds = %bb8
+	load i8** %name_addr, align 4		; <i8*>:23 [#uses=1]
+	call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @"\01LC", i32 0, i32 0), i8* %23 ) nounwind 		; <i32>:24 [#uses=0]
+	br label %bb11
+
+bb11:		; preds = %bb10, %bb8
+	%buf12 = bitcast [1024 x i8]* %buf to i8*		; <i8*> [#uses=1]
+	call i32 @puts( i8* %buf12 ) nounwind 		; <i32>:25 [#uses=0]
+	br label %bb13
+
+bb13:		; preds = %bb11, %bb5, %entry
+	%buf14 = bitcast [1024 x i8]* %buf to i8*		; <i8*> [#uses=1]
+	load %struct.FILE** %f_addr, align 4		; <%struct.FILE*>:26 [#uses=1]
+	call i8* @fgets( i8* %buf14, i32 1024, %struct.FILE* %26 ) nounwind 		; <i8*>:27 [#uses=1]
+	icmp ne i8* %27, null		; <i1>:28 [#uses=1]
+	zext i1 %28 to i8		; <i8>:29 [#uses=1]
+	%toBool15 = icmp ne i8 %29, 0		; <i1> [#uses=1]
+	br i1 %toBool15, label %bb, label %bb16
+
+bb16:		; preds = %bb13
+	load i32* %nmatch, align 4		; <i32>:30 [#uses=1]
+	store i32 %30, i32* %0, align 4
+	load i32* %0, align 4		; <i32>:31 [#uses=1]
+	store i32 %31, i32* %retval, align 4
+	br label %return
+
+return:		; preds = %bb16
+	%retval17 = load i32* %retval		; <i32> [#uses=1]
+	ret i32 %retval17
+}
+
+declare i32 @strlen(i8*) nounwind readonly 
+
+declare i32 @printf(i8*, ...) nounwind 
+
+declare i32 @puts(i8*)
+
+declare i8* @fgets(i8*, i32, %struct.FILE*)
+
+define i32 @grepmain(i32 %argc, i8** %argv) nounwind  {
+entry:
+	%argc_addr = alloca i32		; <i32*> [#uses=5]
+	%argv_addr = alloca i8**		; <i8***> [#uses=6]
+	%retval = alloca i32		; <i32*> [#uses=2]
+	%f = alloca %struct.FILE*		; <%struct.FILE**> [#uses=5]
+	%nmatch = alloca i32		; <i32*> [#uses=4]
+	%i = alloca i32		; <i32*> [#uses=7]
+	alloca i32		; <i32*>:0 [#uses=2]
+	%iftmp.3 = alloca i8*		; <i8**> [#uses=3]
+	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
+	store i32 %argc, i32* %argc_addr
+	store i8** %argv, i8*** %argv_addr
+	load i32* %argc_addr, align 4		; <i32>:1 [#uses=1]
+	icmp sle i32 %1, 1		; <i1>:2 [#uses=1]
+	zext i1 %2 to i8		; <i8>:3 [#uses=1]
+	%toBool = icmp ne i8 %3, 0		; <i1> [#uses=1]
+	br i1 %toBool, label %bb, label %bb1
+
+bb:		; preds = %entry
+	load %struct.FILE** @__stderrp, align 4		; <%struct.FILE*>:4 [#uses=1]
+	bitcast %struct.FILE* %4 to i8*		; <i8*>:5 [#uses=1]
+	call i32 @"\01_fwrite$UNIX2003"( i8* getelementptr ([30 x i8]* @"\01LC1", i32 0, i32 0), i32 1, i32 29, i8* %5 ) nounwind 		; <i32>:6 [#uses=0]
+	call void @exit( i32 0 ) noreturn nounwind 
+	unreachable
+
+bb1:		; preds = %entry
+	store i32 0, i32* %nmatch, align 4
+	load i32* %argc_addr, align 4		; <i32>:7 [#uses=1]
+	icmp eq i32 %7, 2		; <i1>:8 [#uses=1]
+	zext i1 %8 to i8		; <i8>:9 [#uses=1]
+	%toBool2 = icmp ne i8 %9, 0		; <i1> [#uses=1]
+	br i1 %toBool2, label %bb3, label %bb4
+
+bb3:		; preds = %bb1
+	load %struct.FILE** @__stdinp, align 4		; <%struct.FILE*>:10 [#uses=1]
+	load i8*** %argv_addr, align 4		; <i8**>:11 [#uses=1]
+	getelementptr i8** %11, i32 1		; <i8**>:12 [#uses=1]
+	load i8** %12, align 4		; <i8*>:13 [#uses=1]
+	call i32 @grep( i8* %13, %struct.FILE* %10, i8* null ) nounwind 		; <i32>:14 [#uses=0]
+	br label %bb19
+
+bb4:		; preds = %bb1
+	store i32 2, i32* %i, align 4
+	br label %bb17
+
+bb5:		; preds = %bb17
+	load i8*** %argv_addr, align 4		; <i8**>:15 [#uses=1]
+	load i32* %i, align 4		; <i32>:16 [#uses=1]
+	getelementptr i8** %15, i32 %16		; <i8**>:17 [#uses=1]
+	load i8** %17, align 4		; <i8*>:18 [#uses=1]
+	call %struct.FILE* @fopen( i8* %18, i8* getelementptr ([2 x i8]* @"\01LC2", i32 0, i32 0) ) nounwind 		; <%struct.FILE*>:19 [#uses=1]
+	store %struct.FILE* %19, %struct.FILE** %f, align 4
+	load %struct.FILE** %f, align 4		; <%struct.FILE*>:20 [#uses=1]
+	icmp eq %struct.FILE* %20, null		; <i1>:21 [#uses=1]
+	zext i1 %21 to i8		; <i8>:22 [#uses=1]
+	%toBool6 = icmp ne i8 %22, 0		; <i1> [#uses=1]
+	br i1 %toBool6, label %bb7, label %bb8
+
+bb7:		; preds = %bb5
+	load i8*** %argv_addr, align 4		; <i8**>:23 [#uses=1]
+	load i32* %i, align 4		; <i32>:24 [#uses=1]
+	getelementptr i8** %23, i32 %24		; <i8**>:25 [#uses=1]
+	load i8** %25, align 4		; <i8*>:26 [#uses=1]
+	load %struct.FILE** @__stderrp, align 4		; <%struct.FILE*>:27 [#uses=1]
+	call i32 (%struct.FILE*, i8*, ...)* @fprintf( %struct.FILE* %27, i8* getelementptr ([15 x i8]* @"\01LC3", i32 0, i32 0), i8* %26 ) nounwind 		; <i32>:28 [#uses=0]
+	br label %bb16
+
+bb8:		; preds = %bb5
+	load %struct.FILE** %f, align 4		; <%struct.FILE*>:29 [#uses=1]
+	call i32 @setvbuf( %struct.FILE* %29, i8* getelementptr ([1048576 x i8]* @readbuf, i32 0, i32 0), i32 0, i32 1048576 ) nounwind 		; <i32>:30 [#uses=0]
+	load i32* %argc_addr, align 4		; <i32>:31 [#uses=1]
+	icmp sgt i32 %31, 3		; <i1>:32 [#uses=1]
+	zext i1 %32 to i8		; <i8>:33 [#uses=1]
+	%toBool9 = icmp ne i8 %33, 0		; <i1> [#uses=1]
+	br i1 %toBool9, label %bb10, label %bb11
+
+bb10:		; preds = %bb8
+	load i8*** %argv_addr, align 4		; <i8**>:34 [#uses=1]
+	load i32* %i, align 4		; <i32>:35 [#uses=1]
+	getelementptr i8** %34, i32 %35		; <i8**>:36 [#uses=1]
+	load i8** %36, align 4		; <i8*>:37 [#uses=1]
+	store i8* %37, i8** %iftmp.3, align 4
+	br label %bb12
+
+bb11:		; preds = %bb8
+	store i8* null, i8** %iftmp.3, align 4
+	br label %bb12
+
+bb12:		; preds = %bb11, %bb10
+	load i8*** %argv_addr, align 4		; <i8**>:38 [#uses=1]
+	getelementptr i8** %38, i32 1		; <i8**>:39 [#uses=1]
+	load i8** %39, align 4		; <i8*>:40 [#uses=1]
+	load %struct.FILE** %f, align 4		; <%struct.FILE*>:41 [#uses=1]
+	load i8** %iftmp.3, align 4		; <i8*>:42 [#uses=1]
+	call i32 @grep( i8* %40, %struct.FILE* %41, i8* %42 ) nounwind 		; <i32>:43 [#uses=1]
+	icmp sgt i32 %43, 0		; <i1>:44 [#uses=1]
+	zext i1 %44 to i8		; <i8>:45 [#uses=1]
+	%toBool13 = icmp ne i8 %45, 0		; <i1> [#uses=1]
+	br i1 %toBool13, label %bb14, label %bb15
+
+bb14:		; preds = %bb12
+	load i32* %nmatch, align 4		; <i32>:46 [#uses=1]
+	add i32 %46, 1		; <i32>:47 [#uses=1]
+	store i32 %47, i32* %nmatch, align 4
+	br label %bb15
+
+bb15:		; preds = %bb14, %bb12
+	load %struct.FILE** %f, align 4		; <%struct.FILE*>:48 [#uses=1]
+	call i32 @fclose( %struct.FILE* %48 ) nounwind 		; <i32>:49 [#uses=0]
+	br label %bb16
+
+bb16:		; preds = %bb15, %bb7
+	load i32* %i, align 4		; <i32>:50 [#uses=1]
+	add i32 %50, 1		; <i32>:51 [#uses=1]
+	store i32 %51, i32* %i, align 4
+	br label %bb17
+
+bb17:		; preds = %bb16, %bb4
+	load i32* %i, align 4		; <i32>:52 [#uses=1]
+	load i32* %argc_addr, align 4		; <i32>:53 [#uses=1]
+	icmp slt i32 %52, %53		; <i1>:54 [#uses=1]
+	zext i1 %54 to i8		; <i8>:55 [#uses=1]
+	%toBool18 = icmp ne i8 %55, 0		; <i1> [#uses=1]
+	br i1 %toBool18, label %bb5, label %bb19
+
+bb19:		; preds = %bb17, %bb3
+	load i32* %nmatch, align 4		; <i32>:56 [#uses=1]
+	store i32 %56, i32* %0, align 4
+	load i32* %0, align 4		; <i32>:57 [#uses=1]
+	store i32 %57, i32* %retval, align 4
+	br label %return
+
+return:		; preds = %bb19
+	%retval20 = load i32* %retval		; <i32> [#uses=1]
+	ret i32 %retval20
+}
+
+declare i32 @"\01_fwrite$UNIX2003"(i8*, i32, i32, i8*)
+
+declare void @exit(i32) noreturn nounwind 
+
+declare %struct.FILE* @fopen(i8*, i8*)
+
+declare i32 @fprintf(%struct.FILE*, i8*, ...) nounwind 
+
+declare i32 @setvbuf(%struct.FILE*, i8*, i32, i32)
+
+declare i32 @fclose(%struct.FILE*)