簡単なテストlibjitとllvm

「そして、経験、困難な過ちの息子」(c)あなた自身が誰を知っているか



幼少期から、「 だれが勝つか-象かクジラ 」などの質問に興味がありました。 または、例えば、「 誰が強い-トラまたはライオン 」。 私が成長した今、質問は少し変わりました。 今、私は特に興味があります-libjitllvmよりもクールです。



この質問に簡単な方法で答えることはできないことは明らかです。これらは生態学的なニッチが完全に一致しない製品です。賞賛記事から、いわば個人的な経験から。



だから。 簡単なタスクは、エラトステネスのふるい、または素数の検索です。





基本的には、ウィキペディアに示されている実装を採用しました。これに、エラトステインのふるいを何度も実行するサイクルを追加しました。 次のようになりました。



001 : program erato ;

002:

003: procedure eratosphen (n : integer ) ;

004: var

005: a : array [ 0 .. 100000 ] of byte ;

006: q : integer ;

007: i , j : integer ;

008: begin

009: FillChar (a , sizeof (a) , 1 ) ;

010: q := round ( sqrt (n)) ;

011: for i := 2 to q do

012: if a[i] = 1 then

013: begin

014: j := i * i ;

015: while j <= n do

016: begin

017: a[j] := 0 ;

018: j := j + i ;

019: end ;

020: end ;

021: end ;

022:

023: var i : integer ;

024: begin

025: Writeln ( 'Poexali' ) ;

026: for i := 1 to 5000 do

027: eratosphen( 100000 ) ;

028: end .

029:








LIBJITオプション




libjitを使用すると、このプログラムが判明しました。



001 : #include <stdio.h>

002: #include <jit/jit.h>

003:


004: unsigned int myprint ( unsigned int a) {

005: printf( " %d \n " ,a);

006: }

007:

008: jit_function_t main_function, erato;

009:

010:

011: void create_erato ()

012: {

013: jit_type_t params[ 1 ];

014: jit_type_t signature;

015: jit_label_t for_begin = jit_label_undefined;

016: jit_label_t end_for = jit_label_undefined;

017: jit_label_t end_if = jit_label_undefined;

018: jit_label_t while_end = jit_label_undefined;

019: jit_label_t while_begin = jit_label_undefined;

020: jit_label_t print_end = jit_label_undefined;

021: jit_label_t print_begin = jit_label_undefined;

022: jit_label_t print_if = jit_label_undefined;

023: void * args[ 2 ];

024: jit_uint result;

025: jit_value_t n,a,one1,szero,uint1,two2;

026: jit_int arg1;

027: jit_intrinsic_descr_t tofloat = {jit_type_nfloat, NULL , jit_type_uint, NULL };

028: jit_intrinsic_descr_t toint = {jit_type_uint, NULL , jit_type_nfloat, NULL };

029: jit_value_t temp1,temp2,q;

030: jit_value_t i,j,elem;

031: jit_value_t for_cond, if_cond, while_cond, print_cond;

032: jit_value_t tmpi, tmp3,tmp4;

033: /* Create a context to hold the JIT's primary state */

034: /* Build the erato signature */

035: params[ 0 ] = jit_type_uint;

036: signature = jit_type_create_signature (jit_abi_cdecl, jit_type_uint, params, 1 , 1 );

037:

038: /* allocate sieve storage and init it by 1 */

039: n = jit_value_get_param(erato, 0 );

040:

041: //jit_insn_call_native(erato, "print", myprint, signature, &n ,1,0);

042:
a = jit_insn_alloca(erato,n);

043: one1 = jit_value_create_nint_constant(erato, jit_type_ubyte, 1 );

044: szero = jit_value_create_nint_constant(erato,jit_type_ubyte, 0 );

045: jit_insn_memset(erato,a, one1,n);

046: /* convert to float, sqrt and convert to int back */

047: temp1 = jit_insn_call_intrinsic(erato, "convert_to_float" , jit_uint_to_nfloat, & tofloat ,n, NULL );

048: temp2 = jit_insn_sqrt(erato, temp1);

049: q = jit_insn_call_intrinsic(erato, "convert_to_int" ,jit_nfloat_to_uint, & toint ,temp2, NULL );

050:

051: /* for i = 2 to q do*/

052: two2 = jit_value_create_nint_constant(erato,jit_type_uint, 2 );

053: i = jit_value_create(erato,jit_type_uint);

054: jit_insn_store(erato,i,two2);

055: jit_insn_label(erato, & for_begin);

056: for_cond = jit_insn_gt(erato, i, q);

057: jit_insn_branch_if(erato,for_cond, & end_for);

058:

059: // if

060:
elem = jit_insn_load_elem(erato, a, i, jit_type_ubyte);

061: if_cond = jit_insn_eq(erato, elem, one1);

062: jit_insn_branch_if_not(erato,if_cond, & end_if);

063:

064: // j = i*i

065:
j = jit_value_create(erato, jit_type_uint);

066: tmp3 = jit_insn_mul(erato, i, i);

067: jit_insn_store(erato,j, tmp3);

068:

069: // while

070:
jit_insn_label(erato, & while_begin);

071: while_cond = jit_insn_gt(erato,j,n);

072: jit_insn_branch_if(erato, while_cond, & while_end);

073:

074: jit_insn_store_elem(erato,a,j,szero);

075:

076: tmp4 = jit_insn_add(erato,j,i);

077: jit_insn_store(erato,j,tmp4);

078: //while end

079:
jit_insn_branch(erato, & while_begin);

080: jit_insn_label(erato, & while_end);

081: // end if

082:
jit_insn_label(erato, & end_if);

083:

084: // end for i=2 to q

085:
uint1 = jit_value_create_nint_constant(erato,jit_type_uint, 1 );

086: tmpi = jit_insn_add(erato,i,uint1);

087: jit_insn_store(erato,i,tmpi);

088: jit_insn_branch(erato, & for_begin);

089: jit_insn_label(erato, & end_for);

090:

091: jit_insn_return(erato, i);

092:

093: /* Compile the erato */

094: jit_dump_function(stderr, erato, "erato" );

095:

096: jit_function_compile(erato);

097: }

098:

099:

100: void create_main ()

101: {

102: jit_label_t for_begin = jit_label_undefined;

103: jit_label_t end_for = jit_label_undefined;

104: jit_value_t temp_args[ 1 ];

105: jit_value_t temp3,tmpi,one,n,the_i,for_cond,alot,place_for_i;

106: jit_type_t params[ 2 ];

107: jit_type_t signature;

108:

109: n = jit_value_get_param(main_function, 0 );

110: alot = jit_value_get_param(main_function, 1 );

111:

112: one = jit_value_create_nint_constant(main_function,jit_type_int, 1 );

113: the_i = jit_value_create(main_function,jit_type_uint);

114:

115: place_for_i = jit_insn_alloca(main_function, jit_value_create_nint_constant(main_function,jit_type_int, 4 ) );

116:

117: jit_insn_store(main_function,place_for_i,one);

118:

119: jit_insn_label(main_function, & for_begin);

120: the_i = jit_insn_load(main_function,place_for_i);

121:

122: for_cond = jit_insn_gt(main_function, the_i, n);

123: jit_insn_branch_if(main_function,for_cond, & end_for);

124:

125: temp_args[ 0 ] = alot;

126: tmpi = jit_insn_call (main_function, "erato" , erato, NULL , temp_args, 1 , JIT_CALL_NOTHROW);

127:

128: temp3 = jit_insn_add(main_function,the_i,one);

129:

130: jit_insn_store(main_function,place_for_i,temp3);

131:

132: jit_insn_branch(main_function, & for_begin);

133: jit_insn_label(main_function, & end_for);

134:

135: jit_insn_return(main_function, alot);

136:

137: jit_dump_function(stderr, main_function, "main" );

138: jit_function_compile(main_function);

139: // jit_dump_function(stderr, main_function, "main_compiled");

140:


141: }

142:

143: int main ( int argc, char ** argv)

144: {

145: jit_context_t context;

146: void * args[ 2 ];

147: jit_uint result;

148: jit_int arg1,arg2;

149: jit_type_t params[ 2 ];

150: jit_type_t signature,sign1;

151:

152: context = jit_context_create();

153:

154: /* Lock the context while we build and compile the function */

155: jit_context_build_start(context);

156:

157: /* Build the function signature */

158: params[ 0 ] = jit_type_int;

159: signature = jit_type_create_signature (jit_abi_cdecl, jit_type_int, params, 1 , 1 );

160:

161: erato = jit_function_create(context, signature);

162: create_erato();

163:

164: params[ 0 ] = jit_type_int;

165: params[ 1 ] = jit_type_int;

166: signature = jit_type_create_signature (jit_abi_cdecl, jit_type_int, params, 2 , 1 );

167:

168: main_function = jit_function_create(context, signature);

169: create_main();

170:

171: /* Unlock the context */

172: jit_context_build_end(context);

173:

174: // jit_dump_function(stderr, main_function, "main");

175:
/* Execute the function and print the result */

176: arg1 = 100000 ;

177: arg2 = 50000 ;

178: args[ 0 ] = & arg1;

179: args[ 1 ] = & arg2;

180:

181: jit_function_apply(main_function, args, & result);

182:

183: /* Clean up */

184: jit_context_destroy(context);

185:

186: /* Finished */

187: return 0 ;

188: }

189:







001 : #include <stdio.h>

002: #include <jit/jit.h>

003:


004: unsigned int myprint ( unsigned int a) {

005: printf( " %d \n " ,a);

006: }

007:

008: jit_function_t main_function, erato;

009:

010:

011: void create_erato ()

012: {

013: jit_type_t params[ 1 ];

014: jit_type_t signature;

015: jit_label_t for_begin = jit_label_undefined;

016: jit_label_t end_for = jit_label_undefined;

017: jit_label_t end_if = jit_label_undefined;

018: jit_label_t while_end = jit_label_undefined;

019: jit_label_t while_begin = jit_label_undefined;

020: jit_label_t print_end = jit_label_undefined;

021: jit_label_t print_begin = jit_label_undefined;

022: jit_label_t print_if = jit_label_undefined;

023: void * args[ 2 ];

024: jit_uint result;

025: jit_value_t n,a,one1,szero,uint1,two2;

026: jit_int arg1;

027: jit_intrinsic_descr_t tofloat = {jit_type_nfloat, NULL , jit_type_uint, NULL };

028: jit_intrinsic_descr_t toint = {jit_type_uint, NULL , jit_type_nfloat, NULL };

029: jit_value_t temp1,temp2,q;

030: jit_value_t i,j,elem;

031: jit_value_t for_cond, if_cond, while_cond, print_cond;

032: jit_value_t tmpi, tmp3,tmp4;

033: /* Create a context to hold the JIT's primary state */

034: /* Build the erato signature */

035: params[ 0 ] = jit_type_uint;

036: signature = jit_type_create_signature (jit_abi_cdecl, jit_type_uint, params, 1 , 1 );

037:

038: /* allocate sieve storage and init it by 1 */

039: n = jit_value_get_param(erato, 0 );

040:

041: //jit_insn_call_native(erato, "print", myprint, signature, &n ,1,0);

042:
a = jit_insn_alloca(erato,n);

043: one1 = jit_value_create_nint_constant(erato, jit_type_ubyte, 1 );

044: szero = jit_value_create_nint_constant(erato,jit_type_ubyte, 0 );

045: jit_insn_memset(erato,a, one1,n);

046: /* convert to float, sqrt and convert to int back */

047: temp1 = jit_insn_call_intrinsic(erato, "convert_to_float" , jit_uint_to_nfloat, & tofloat ,n, NULL );

048: temp2 = jit_insn_sqrt(erato, temp1);

049: q = jit_insn_call_intrinsic(erato, "convert_to_int" ,jit_nfloat_to_uint, & toint ,temp2, NULL );

050:

051: /* for i = 2 to q do*/

052: two2 = jit_value_create_nint_constant(erato,jit_type_uint, 2 );

053: i = jit_value_create(erato,jit_type_uint);

054: jit_insn_store(erato,i,two2);

055: jit_insn_label(erato, & for_begin);

056: for_cond = jit_insn_gt(erato, i, q);

057: jit_insn_branch_if(erato,for_cond, & end_for);

058:

059: // if

060:
elem = jit_insn_load_elem(erato, a, i, jit_type_ubyte);

061: if_cond = jit_insn_eq(erato, elem, one1);

062: jit_insn_branch_if_not(erato,if_cond, & end_if);

063:

064: // j = i*i

065:
j = jit_value_create(erato, jit_type_uint);

066: tmp3 = jit_insn_mul(erato, i, i);

067: jit_insn_store(erato,j, tmp3);

068:

069: // while

070:
jit_insn_label(erato, & while_begin);

071: while_cond = jit_insn_gt(erato,j,n);

072: jit_insn_branch_if(erato, while_cond, & while_end);

073:

074: jit_insn_store_elem(erato,a,j,szero);

075:

076: tmp4 = jit_insn_add(erato,j,i);

077: jit_insn_store(erato,j,tmp4);

078: //while end

079:
jit_insn_branch(erato, & while_begin);

080: jit_insn_label(erato, & while_end);

081: // end if

082:
jit_insn_label(erato, & end_if);

083:

084: // end for i=2 to q

085:
uint1 = jit_value_create_nint_constant(erato,jit_type_uint, 1 );

086: tmpi = jit_insn_add(erato,i,uint1);

087: jit_insn_store(erato,i,tmpi);

088: jit_insn_branch(erato, & for_begin);

089: jit_insn_label(erato, & end_for);

090:

091: jit_insn_return(erato, i);

092:

093: /* Compile the erato */

094: jit_dump_function(stderr, erato, "erato" );

095:

096: jit_function_compile(erato);

097: }

098:

099:

100: void create_main ()

101: {

102: jit_label_t for_begin = jit_label_undefined;

103: jit_label_t end_for = jit_label_undefined;

104: jit_value_t temp_args[ 1 ];

105: jit_value_t temp3,tmpi,one,n,the_i,for_cond,alot,place_for_i;

106: jit_type_t params[ 2 ];

107: jit_type_t signature;

108:

109: n = jit_value_get_param(main_function, 0 );

110: alot = jit_value_get_param(main_function, 1 );

111:

112: one = jit_value_create_nint_constant(main_function,jit_type_int, 1 );

113: the_i = jit_value_create(main_function,jit_type_uint);

114:

115: place_for_i = jit_insn_alloca(main_function, jit_value_create_nint_constant(main_function,jit_type_int, 4 ) );

116:

117: jit_insn_store(main_function,place_for_i,one);

118:

119: jit_insn_label(main_function, & for_begin);

120: the_i = jit_insn_load(main_function,place_for_i);

121:

122: for_cond = jit_insn_gt(main_function, the_i, n);

123: jit_insn_branch_if(main_function,for_cond, & end_for);

124:

125: temp_args[ 0 ] = alot;

126: tmpi = jit_insn_call (main_function, "erato" , erato, NULL , temp_args, 1 , JIT_CALL_NOTHROW);

127:

128: temp3 = jit_insn_add(main_function,the_i,one);

129:

130: jit_insn_store(main_function,place_for_i,temp3);

131:

132: jit_insn_branch(main_function, & for_begin);

133: jit_insn_label(main_function, & end_for);

134:

135: jit_insn_return(main_function, alot);

136:

137: jit_dump_function(stderr, main_function, "main" );

138: jit_function_compile(main_function);

139: // jit_dump_function(stderr, main_function, "main_compiled");

140:


141: }

142:

143: int main ( int argc, char ** argv)

144: {

145: jit_context_t context;

146: void * args[ 2 ];

147: jit_uint result;

148: jit_int arg1,arg2;

149: jit_type_t params[ 2 ];

150: jit_type_t signature,sign1;

151:

152: context = jit_context_create();

153:

154: /* Lock the context while we build and compile the function */

155: jit_context_build_start(context);

156:

157: /* Build the function signature */

158: params[ 0 ] = jit_type_int;

159: signature = jit_type_create_signature (jit_abi_cdecl, jit_type_int, params, 1 , 1 );

160:

161: erato = jit_function_create(context, signature);

162: create_erato();

163:

164: params[ 0 ] = jit_type_int;

165: params[ 1 ] = jit_type_int;

166: signature = jit_type_create_signature (jit_abi_cdecl, jit_type_int, params, 2 , 1 );

167:

168: main_function = jit_function_create(context, signature);

169: create_main();

170:

171: /* Unlock the context */

172: jit_context_build_end(context);

173:

174: // jit_dump_function(stderr, main_function, "main");

175:
/* Execute the function and print the result */

176: arg1 = 100000 ;

177: arg2 = 50000 ;

178: args[ 0 ] = & arg1;

179: args[ 1 ] = & arg2;

180:

181: jit_function_apply(main_function, args, & result);

182:

183: /* Clean up */

184: jit_context_destroy(context);

185:

186: /* Finished */

187: return 0 ;

188: }

189:










一般的な印象-それは非常に簡単に書かれ、ドキュメントは詳細であり、例があります-私は+



LLVMオプション




001 : #include "llvm/DerivedTypes.h"

002: #include "llvm/LLVMContext.h"

003: #include "llvm/Module.h"

004: #include "llvm/Analysis/Verifier.h"

005: #include "llvm/Support/IRBuilder.h"

006: #include "llvm/ExecutionEngine/ExecutionEngine.h"

007: #include "llvm/ExecutionEngine/JIT.h"

008: #include "llvm/PassManager.h"

009: #include "llvm/Analysis/Verifier.h"

010: #include "llvm/Target/TargetData.h"

011: #include "llvm/Target/TargetSelect.h"

012: #include "llvm/Transforms/Scalar.h"

013:

014: #include <iostream>

015: #include <vector>

016: #include <list>

017: #include <map>

018: #include <stdlib.h>

019: #include <cstring>

020: #include <string>

021: #include <stdio.h>

022:
using namespace llvm;

023: using namespace std;

024:

025: Value * ErrorV( const char * Str)

026: {

027: cerr << Str << endl;

028: return 0 ;

029: }

030:

031: static Module * TheModule;

032: static IRBuilder <> Builder(getGlobalContext());

033: static map < string, Value * > NamedValues;

034: static ExecutionEngine * TheExecutionEngine;

035:

036: int main()

037: {

038: InitializeNativeTarget();

039: LLVMContext & Context = getGlobalContext();

040: TheModule = new Module( "erato" , Context);

041:

042: std :: string ErrStr;

043: TheExecutionEngine =

044: EngineBuilder(TheModule).setErrorStr( & ErrStr).create();

045: if ( ! TheExecutionEngine) {

046: fprintf(stderr, "Could not create ExecutionEngine: %s \n " ,

047: ErrStr.c_str());

048: exit( 1 );

049: }

050:

051:

052: const Type * voidType = Type :: getVoidTy(Context);

053: const Type * i32Type = IntegerType :: get(Context, 32 );

054: const Type * i8Type = IntegerType :: get(Context, 8 );

055: const Type * FType = Type :: getDoubleTy(Context);

056: const Type * SType = PointerType :: get(i8Type, 0 );

057:

058: Value * zero = ConstantInt :: get(i32Type, 0 );

059: Value * one = ConstantInt :: get(i32Type, 1 );

060: Value * two = ConstantInt :: get(i32Type, 2 );

061: Constant * n100000 = ConstantInt :: get(i32Type, 100000 );

062: Constant * n50000 = ConstantInt :: get(i32Type, 50000 );

063:

064: Value * i8zero = ConstantInt :: get(i8Type, 0 );

065: Value * i8one = ConstantInt :: get(i8Type, 1 );

066:

067:

068:

069: vector < const Type *> def_args;

070:

071: def_args.push_back(SType);

072: FunctionType * fdefinition = FunctionType :: get(voidType, def_args, true );

073: func_printf = Function :: Create(fdefinition, GlobalValue :: ExternalLinkage, "printf" , TheModule);

074: func_printf -> setCallingConv(CallingConv :: C);

075: def_args.clear();

076:

077: // declare double @llvm.sqrt.f64(double) nounwind readonly

078:


079: def_args.push_back(FType);

080: FunctionType * fdefinition_sqrt = FunctionType :: get(FType, def_args, false );

081: Function * func_sqrt = Function :: Create(fdefinition_sqrt, GlobalValue :: ExternalLinkage, "llvm.sqrt.f64" , TheModule);

082: func_sqrt -> setCallingConv(CallingConv :: C);

083: def_args.clear();

084:

085: // declare void @llvm.memset.i32(i8* nocapture, i8, i32, i32) nounwind

086:


087: def_args.push_back(SType);

088: def_args.push_back(i8Type);

089: def_args.push_back(i32Type);

090: def_args.push_back(i32Type);

091: FunctionType * fdefinition_memset = FunctionType :: get(voidType, def_args, false );

092: Function * func_memset = Function :: Create(fdefinition_memset, GlobalValue :: ExternalLinkage, "llvm.memset.i32" , TheModule);

093: func_memset -> setCallingConv(CallingConv :: C);

094: def_args.clear();

095:

096:

097: // Construct eratosphene()

098:
Function * func_ef = cast < Function > (TheModule -> getOrInsertFunction( "erato" , voidType, i32Type, NULL ));

099: func_ef -> setCallingConv(CallingConv :: C);

100: BasicBlock * ef_start_block = BasicBlock :: Create(Context, "efcode" , func_ef);

101: IRBuilder <> efcodeIR(ef_start_block);

102: format = efcodeIR.CreateGlobalStringPtr( "%d" , ".format" );

103:

104: BasicBlock * ef_mainloop = BasicBlock :: Create(Context, "Main_loop" , func_ef);

105: BasicBlock * ef_mainloopbody = BasicBlock :: Create(Context, "Main_loop.body" , func_ef);

106: BasicBlock * ef_ifbody = BasicBlock :: Create(Context, "if.body" , func_ef);

107: BasicBlock * ef_whileloop = BasicBlock :: Create(Context, "While_loop" , func_ef);

108: BasicBlock * ef_whileloopbody = BasicBlock :: Create(Context, "While_loop.body" , func_ef);

109: BasicBlock * ef_mainloopcont = BasicBlock :: Create(Context, "Main_loop.cont" , func_ef);

110: BasicBlock * ef_mainloopend = BasicBlock :: Create(Context, "Main_loop.end" , func_ef);

111:

112: // Set name for argument

113:
Function :: arg_iterator ef_args = func_ef -> arg_begin();

114: Argument * upbound = ef_args;

115: upbound -> setName( "upbound" );

116:

117: Value * a = efcodeIR.CreateAlloca(i8Type, upbound, "a" );

118: Value * temp1 = efcodeIR.CreateUIToFP(upbound, FType, "tmp.1" );

119: Value * temp2 = efcodeIR.CreateCall(func_sqrt, temp1, "temp.2" );

120: Value * q = efcodeIR.CreateFPToUI(temp2, i32Type, "q" );

121: efcodeIR.CreateCall4(func_memset, a, i8one, upbound, one);

122: efcodeIR.CreateBr(ef_mainloop);

123: efcodeIR.SetInsertPoint(ef_mainloop);

124: PHINode * i = efcodeIR.CreatePHI(i32Type, "i" );

125: i -> addIncoming(two, ef_start_block);

126: Value * cond = efcodeIR.CreateICmpUGT(i, q, "cond" );

127: efcodeIR.CreateCondBr(cond, ef_mainloopend, ef_mainloopbody);

128: efcodeIR.SetInsertPoint(ef_mainloopbody);

129: Value * eptr = efcodeIR.CreateGEP(a, i, "eptr" );

130: Value * elem = efcodeIR.CreateLoad(eptr, "elem" );

131: Value * ifcond = efcodeIR.CreateICmpEQ(i8zero, elem, "ifcond" );

132: efcodeIR.CreateCondBr(ifcond, ef_mainloopcont, ef_ifbody);

133: efcodeIR.SetInsertPoint(ef_ifbody);

134: Value * jfirst = efcodeIR.CreateMul(i, i, "j.first" );

135: efcodeIR.CreateBr(ef_whileloop);

136: efcodeIR.SetInsertPoint(ef_whileloop);

137: PHINode * j = efcodeIR.CreatePHI(i32Type, "j" );

138: j -> addIncoming(jfirst, ef_ifbody);

139: Value * whilecond = efcodeIR.CreateICmpUGT(j, upbound, "while.cond" );

140: efcodeIR.CreateCondBr(whilecond, ef_mainloopcont, ef_whileloopbody);

141: efcodeIR.SetInsertPoint(ef_whileloopbody);

142: Value * elemref = efcodeIR.CreateGEP(a, j, "elem.ref" );

143: efcodeIR.CreateStore(i8zero, elemref);

144: Value * jnext = efcodeIR.CreateAdd(j, i, "j.next" );

145: j -> addIncoming(jnext, ef_whileloopbody);

146: efcodeIR.CreateBr(ef_whileloop);

147: efcodeIR.SetInsertPoint(ef_mainloopcont);

148: Value * inext = efcodeIR.CreateAdd(i, one, "i.next" );

149: i -> addIncoming(inext, ef_mainloopcont);

150: efcodeIR.CreateBr(ef_mainloop);

151:

152: efcodeIR.SetInsertPoint(ef_mainloopend);

153: efcodeIR.CreateRetVoid();

154:

155: // Contruct void main()

156:
Function * func_main = cast < Function > (TheModule -> getOrInsertFunction( "main" , voidType, NULL ));

157: func_main -> setCallingConv(CallingConv :: C);

158: BasicBlock * mnblock = BasicBlock :: Create(Context, "maincode" , func_main);

159: IRBuilder <> mainIR(mnblock);

160:

161: BasicBlock * mn_testloop = BasicBlock :: Create(Context, "Test_loop" , func_main);

162: BasicBlock * mn_tloopbody = BasicBlock :: Create(Context, "Tloop_body" , func_main);

163: BasicBlock * mn_endloop = BasicBlock :: Create(Context, "End_loop" , func_main);

164:

165: mainIR.CreateBr(mn_testloop);

166: mainIR.SetInsertPoint(mn_testloop);

167: PHINode * maini = mainIR.CreatePHI(i32Type, "i" );

168: maini -> addIncoming(zero, mnblock);

169: Value * mainloopcond = mainIR.CreateICmpUGT(maini, n100000, "loop_cond" );

170: mainIR.CreateCondBr(mainloopcond, mn_endloop, mn_tloopbody);

171: mainIR.SetInsertPoint(mn_tloopbody);

172: mainIR.CreateCall(func_ef, n50000);

173: Value * maininext = mainIR.CreateAdd(maini, one, "i.next" );

174: maini -> addIncoming(maininext, mn_tloopbody);

175: mainIR.CreateBr(mn_testloop);

176: mainIR.SetInsertPoint(mn_endloop);

177: mainIR.CreateRetVoid();

178:

179: TheModule -> dump();

180:

181: void * FPtr = TheExecutionEngine -> getPointerToFunction(func_main);

182: void ( * FP) () = ( void ( * )()) FPtr;

183: FP();

184: }

185:








だから、私たちは比較します:



冗長性 -鼻孔内のほとんど鼻孔。 そことそこの両方で、あなたは数行/コメントを投げたり、数行を追加することができますが、これは天気を作りません-コードサイズはほぼ同じです。



速度で -

LibJitオプション:



walrus@home:~/sand/erato$ gcc t2_test.c -o ts -ljit

walrus@home:~/sand/erato$ for i in `seq 1 10`; do /usr/bin/time -f '%U' ./ts; done

14.22

14.17

14.12

14.19

14.18

14.24

14.15

14.14

14.15

14.15







14.17秒の平均値



LLVMオプション-

walrus@home:~/sand/erato/llvm$ g++ ts.cc -o ts `llvm-config --cxxflags --libs` -lrt -ldl

walrus@home:~/sand/erato/llvm$ for i in `seq 1 10`; do /usr/bin/time -f '%U' ./ts; done

13.83

13.75

13.82

13.76

13.76

13.78

13.76

13.76

13.76

13.76







平均値は13.77秒です。



違いはllvmを支持して2.88%でした。



ところで、gcc -O1を使用して準備された同様のCプログラムは、同じ13.79秒を与えました。



待ち伏せ -llvmの気に入らない不快な機能。 libjitでは-この犬は関数を呼び出すときにレジスタの値を保存しません! そのままの状態を維持するために必要なのは、関数を呼び出す前にメモリに保存することです。 そのjibjit-ovskoyと外部の両方。 私はドキュメントでこれを見つけませんでした、そしてそれがどんな種類の問題であるかを理解しようとして数時間を費やしました。 最後に、生成されたアセンブラの検討のみが問題を明らかにしました。



道徳





ええと...私は何かを理解しません、どのような道徳



All Articles