Mercurial > hg > Members > shinya > pyrect
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*)