llvm-2.9 PB Code Generator progress

Sujets variés concernant le développement en PureBasic
idle
Messages : 63
Inscription : ven. 30/juil./2010 2:31

llvm-2.9 PB Code Generator progress

Message par idle »

voici les llvm-2.9 PB include et binaries, si quelqu'un est intéressé?

llvm2.9.zip

If you want to build it your self
Grom a écrit :
Download the 2.9 version ( source code ) http://llvm.org/releases/
- Extract to your desktop
- Open Terminal and go into llvm-2.9 directories
- ./configure --enable-shared
- make
- Drink coffee 20 mins
Dernière modification par idle le mer. 06/juil./2011 4:09, modifié 4 fois.
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: llvm-2.8

Message par G-Rom »

oui , moi, merci.
:D
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: llvm-2.8

Message par Kwai chang caine »

Je ne sais pas à quoi ça sert, comme dab, mais quand on te fait un cadeau, faut toujours dire merci 8)

I don't know what is the function of this code, like usually :oops: , but when somebody give a present, it's important to always say thanks :roll:
Thanks a lot IDLE 8)
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Moi non plus je ne sais pas ce que sais, j'ai essayé de compiler mais j' ai une 20 ène de warning!
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: llvm-2.8

Message par Kwai chang caine »

Alors la...si quelqu'un de ton niveau ne connait pas 8O
Me v'la rassuré 8)
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
idle
Messages : 63
Inscription : ven. 30/juil./2010 2:31

Re: llvm-2.8

Message par idle »

pour Linux utilise le distros package manager et recherche pour llvm-2.8

pour Windows, il n'est pas facile, vous aurez besoin de construire llvm.
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: llvm-2.8

Message par G-Rom »

C'est pour fabriqué des compilateurs.http://fr.wikipedia.org/wiki/Low_Level_Virtual_Machine
D'après Fred , un jour peut être , le compilateur sera basé dessus.
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: llvm-2.8

Message par Kwai chang caine »

Merci GRom 8)
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
idle
Messages : 63
Inscription : ven. 30/juil./2010 2:31

Re: llvm-2.8

Message par idle »

J'ai mis à jour le fichier d'inclusion, ce n'était pas l'importation des fonctions lto

Altered l'exemple de Fibonacci un peu pour le rendre plus facile à suivre
Il va maintenant vider le bytecode de la Jit de fichier, puis le compiler en code natif
(pas que ça va fonctionner, il suffit de tester les fonctionnalités)

Je suis un peu confus sur la façon dont votre censé aller sur la définition des fonctions qui ont de multiples paramètres
LLVMFunctionType (ReturnType.i, * ParamTypes.i, ParamCount, IsVarArg);
serait-il dire que vous allouer une mémoire tampon pour les références de type et de les pousser dans la mémoire tampon
puis définissez le nombre et vararg de vrai?

probably makes more sense in English!

I've Updated the include file, it wasn't importing the lto functions

Altered the Fibonacci example a bit to make it easier to follow
It will now dump the bytecode from the Jit to file and then compile it to native code
(not that it'll run, just testing the functionality)

I'm a bit confused about how your supposed to go about defining functions that have multiple parameters
LLVMFunctionType(ReturnType.i,*ParamTypes.i,ParamCount,IsVarArg);
would it imply that you allocate a buffer for the type references and poke them into the buffer
then set the count and varArg to true?
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: llvm-2.8

Message par G-Rom »

I'm a bit confused about how your supposed to go about defining functions that have multiple parameters
LLVMFunctionType(ReturnType.i,*ParamTypes.i,ParamCount,IsVarArg);
would it imply that you allocate a buffer for the type references and poke them into the buffer
then set the count and varArg to true?
Very difficult to make response.
If you read the doxygen documentation , varArg is the number of arguments , and you i think you must poke params into *ParamTypes.
idle
Messages : 63
Inscription : ven. 30/juil./2010 2:31

Re: llvm-2.8

Message par idle »

We probably can just use dim Array.i(x) and pass @Array(0) in Params
but if that doesn't work it's easy enough to do with a memory buffer.
since there are a number of functions that take or return varArgs
perhaps it would be better to make some helper macros in the headed.
idle
Messages : 63
Inscription : ven. 30/juil./2010 2:31

Re: llvm-2.8

Message par idle »

joué avec le JIT aujourd'hui mais il fonctionne comme un chien!
Je ne comprends pas!

http://www.purebasic.fr/english/viewtop ... 15&t=46544
idle
Messages : 63
Inscription : ven. 30/juil./2010 2:31

Re: llvm-2.8

Message par idle »

google translate:
J'ai essayé de faire un processus itératif de Fibonacci et je ne suis pas sûr de ce que le problème est.
Alors je préfère utiliser les paramètres d'entrée ArgX% dans la boucle
Je suis à une perte complète comment sous une d'elle, puis on assigne aux Arg1%?

Alors j'ai ajouté un D local pour stocker les ArgX sorte qu'il peut être chargé et stocké
mais il ne s'exécute que les boucles une fois la procédure retourne toujours 2 pour l'entrée de plus de 2
c'est peut-être besoin d'un noeud Phi

Voici la sortie de la fonction de mise, il est assez facile à suivre et ressemble à ça devrait fonctionner
mais il ne fait pas!


I tried to do an iterative Fibonacci and I'm not sure what the problem is.
While I'd prefer to use the input parameter %ArgX in the loop
I'm at a complete loss how to sub 1 from it and then assign it back to %Arg1?

So I added a local D to store ArgX so it can be loaded and stored
but it only executes the loops once and the procedure always returns 2 for input larger than 2
maybe it need a Phi node

Here's the out put of the function, it's easy enough to follow and looks like it should work
but it doesn't!

Code : Tout sélectionner


define fastcc i32 @fib2(i32 %ArgX) {
EntryBlock:
  %A = alloca i32   ;stack storage
  %B = alloca i32
  %C = alloca i32
  %D = alloca i32
  store i32 1, i32* %A
  store i32 1, i32* %B
  store i32 0, i32* %C
  store i32 %ArgX, i32* %D
  %cond = icmp sle i32 %ArgX, 2        ; Argx <= 2
  br i1 %cond, label %IF, label %Else

IF:                                               ; preds = %EntryBlock
  ret i32 1

Else:                                             ; preds = %while, %EntryBlock
  %PD = load i32* %D
  %cond1 = icmp sge i32 %PD, 2       ; PD >= 2
  br i1 %cond1, label %while, label %ewhile

while:                                            ; preds = %Else
  %pA = load i32* %A
  %pB = load i32* %B
  %addab = add i32 %pA, %pB
  store i32 %addab, i32* %C
  store i32 %pA, i32* %B
  store i32 %addab, i32* %A
  %sub = sub i32 %PD, 1             ;pd-1
  store i32 %sub, i32* %D            ;d=pd
  br label %Else                          ;jump :else

ewhile:                                           ; preds = %Else
  %CR = load i32* %C
  ret i32 %CR
}


The dirty code

Code : Tout sélectionner

;  Fibonacci function executed by JIT. 
;  Origonal c example from llvm fibonaci example 
;  
;  Author idle - a hack To see how llvm works 
;  Shows How to create a llvm module in memory
;  Build a Function    
;  Create a Function optimizer 
;  Dump the module To byte code 
;  Load the byte code file and produce native object code 
;  
;  The fib function calulates the number of factors    
;   
;  Procedure fib(argx.i)
;  If argx<=2
;     ProcedureReturn 1
;   Else  
;    ProcedureReturn fib(argx-1)+fib(argx-2)
;  EndIf
;  EndProcedure
;
; Once we have this, we compile the module via JIT, then execute the `fib'
; function And Return result To a driver, i.e. To a "host program".
;===----------------------------------------------------------------------===''

IncludeFile "llvm-2.8.pbi"

;dirty helper to read var arg strings 
Procedure.s ReadVarString(*chr)
 Protected strout.s,tmp.s 
 Protected *mem 
 *mem = *chr 
 If *mem > 64000
 Repeat
    tmp = PeekS(*chr+ct)
    If tmp <> ""
      strout+tmp+#LF$ 
    Else 
      Break 
    EndIf  
    ct+Len(tmp)+1
  ForEver
 EndIf
ProcedureReturn strout
EndProcedure  

Procedure fibPB(argx.i)
  If argx<=2
    ProcedureReturn 1
  Else  
   ProcedureReturn fibPB(argx-1)+fibPB(argx-2)
  EndIf
EndProcedure

Procedure fibPB2(argx.i)
  Protected a,b,c
  If argx <= 2
    ProcedureReturn 1
  Else 
    a = 1
    b = 1
    While argx > 2
      c = a + b;
      b = a;
      a = c;
      argx-1;
    Wend
    ProcedureReturn c
 EndIf    
EndProcedure
Procedure CreateFibFunction(M.i,Context.i)     
    Protected FunctionReturnType
    Protected IntType 
    
    ;Procedure.i fib(x.i)
    ;function only uses and int type, create an int type.
    intType = LLVMInt32Type()
    
    ;Function returns an int And takes an int as the only parameter.
    FunctionReturnType = LLVMFunctionType(IntType,@IntType,1,0)
    
    ;Create the fib function definition And insert it into the module M. 
    Fib2 = LLVMAddFunction(M, "fib2",FunctionReturnType)
    ;Set the function call convention to FastCall so it can utilize tail call 
    LLVMSetFunctionCallConv(Fib2,#LLVMFastCallConv)
        
    ;Add a basic block To the function.
     BB = LLVMAppendBasicBlockInContext(Context, Fib2, "EntryBlock")
    ;Get a pointer to the ArgX.i and add to function...
    ArgX = LLVMGetFirstParam(Fib2) ; Get the arg.
    LLVMSetValueName(ArgX, "ArgX") ; Give it a symbolic name.
   
    ;When using the C bindings, you have to use a BuilderRef To create any instructions.
    Builder = LLVMCreateBuilderInContext(Context)
    ;Set the builder to insert at the first BasicBlock.
    LLVMPositionBuilderAtEnd(Builder, BB)
    A = LLVMBuildAlloca(Builder, IntType,"A");
    B = LLVMBuildAlloca(Builder, IntType,"B");
    C = LLVMBuildAlloca(Builder, IntType,"C");
    D =  LLVMBuildAlloca(Builder, IntType,"D");   
    One = LLVMConstInt(IntType, 1, 0)
    LLVMBuildStore(Builder,One,A);
    LLVMBuildStore(Builder,One,B);
    Zero = LLVMConstInt(IntType, 0, 0)
    LLVMBuildStore(Builder,Zero,C)
    LLVMBuildStore(Builder,ArgX,D)
    
    ;Create and build the conditional branch "if argX <= 2" 
     IFBB = LLVMAppendBasicBlockInContext(Context, Fib2, "IF")
    ;Create two blocks for the Branches  If argx<=2 : RetBB : else : RecurseBB   
     ElseBB = LLVMAppendBasicBlockInContext(Context, Fib2, "Else")
     Two = LLVMConstInt(IntType, 2, 0)
     CondInst = LLVMBuildICmp(Builder, #LLVMIntSLE, ArgX,Two, "cond")
     LLVMBuildCondBr(Builder, CondInst, IFBB, ElseBB)
     LLVMPositionBuilderAtEnd(Builder, IFBB)
     LLVMBuildRet(Builder,One)
     LLVMPositionBuilderAtEnd(Builder, ElseBB)
     
    WhileBB = LLVMAppendBasicBlockInContext(Context, Fib2, "while") 
    EWhileBB = LLVMAppendBasicBlockInContext(Context, Fib2, "ewhile") 
    
    PD  = LLVMBuildLoad(Builder,D,"PD");
    CondInst1 = LLVMBuildICmp(Builder, #LLVMIntSGE, PD, Two, "cond")
    LLVMBuildCondBr(Builder, CondInst1, WhileBB, EWhileBB)
    LLVMPositionBuilderAtEnd(Builder, WhileBB)   
    
    PA  = LLVMBuildLoad(Builder,A,"pA");
    PB =  LLVMBuildLoad(Builder,B,"pB");
    AddAB = LLVMBuildAdd(Builder,PA,PB,"addab")
    LLVMBuildStore(Builder,AddAB,C);
    LLVMBuildStore(Builder,PA,B);
    LLVMBuildStore(Builder,AddAB,A);
   
    sub = LLVMBuildSub(Builder,PD,One,"sub")
    LLVMBuildStore(Builder,sub,D);
    
    jump = LLVMBuildBr(Builder,ElseBB);
    
    LLVMPositionBuilderAtEnd(Builder, EWhileBB)
    ;Create the return instruction And add it To the basic block
    CR  = LLVMBuildLoad(Builder,C,"CR");
    LLVMBuildRet(Builder, CR)
    
    ;Don't forget to free the builder.
    LLVMDisposeBuilder(Builder)
    
    ;Return the function ref
    ProcedureReturn Fib2
    
  EndProcedure
Procedure CreateFibFunction1(M.i,Context.i)     
    Protected FunctionReturnType
    Protected IntType 
    
    ;Procedure.i fib(x.i)
    ;function only uses and int type, create an int type.
    intType = LLVMInt32Type()
    
    ;Function returns an int And takes an int as the only parameter.
    FunctionReturnType = LLVMFunctionType(IntType,@IntType,1,0)
    
    ;Create the fib function definition And insert it into the module M. 
    FibF = LLVMAddFunction(M, "fib",FunctionReturnType)
    ;Set the function call convention to FastCall so it can utilize tail call 
    LLVMSetFunctionCallConv(FibF,#LLVMFastCallConv)
    
    
    ;Add a basic block To the function.
     BB = LLVMAppendBasicBlockInContext(Context, FibF, "EntryBlock")
        
    ;Make the Constants returns a pointer to the constant.
    ; fib(argx->>"1"<<)+fib(argx->>"2"<<)
    One = LLVMConstInt(IntType, 1, 0)
    Two = LLVMConstInt(IntType, 2, 0)
    
    ;Get a pointer to the ArgX.i and add to function...
    ArgX = LLVMGetFirstParam(FibF) ; Get the arg.
    LLVMSetValueName(ArgX, "ArgX") ; Give it a symbolic name.
   
    ;When using the C bindings, you have to use a BuilderRef To create any instructions.
    Builder = LLVMCreateBuilderInContext(Context)
    ;Set the builder to insert at the first BasicBlock.
    LLVMPositionBuilderAtEnd(Builder, BB)
    
    ;Create and build the conditional branch "if argX <= 2" 
    CondInst = LLVMBuildICmp(Builder, #LLVMIntSLE, ArgX, Two, "cond")
    
    ;Create two blocks for the Branches  If argx<=2 : RetBB : else : RecurseBB   
    RetBB = LLVMAppendBasicBlockInContext(Context, FibF, "return")
    RecurseBB = LLVMAppendBasicBlockInContext(Context, FibF, "recurse")
    
    LLVMBuildCondBr(Builder, CondInst, RetBB, RecurseBB)
    
   ;Create: ProcedureReturn 1
    LLVMPositionBuilderAtEnd(Builder, RetBB)
    LLVMBuildRet(Builder,One)
    
    ;Create fib(x-1)
    LLVMPositionBuilderAtEnd(Builder, RecurseBB)
    Subtr = LLVMBuildSub(Builder, ArgX, One, "arg")
    CallFibX1 = LLVMBuildCall(Builder, FibF, @Subtr, 1, "fibx1")
    ;LLVMSetTailCall(CallFibX1, 1)  ;let the optimzer deal with it
    
    ;Create fib(x-2)
    Subtr = LLVMBuildSub(Builder, ArgX, Two, "arg")
    CallFibX2 = LLVMBuildCall(Builder, FibF, @Subtr, 1, "fibx2")
    ;LLVMSetTailCall(CallFibX2, 1)  ;let the optimzer deal with it
    
    ;fib(x-1)+fib(x-2)
    Sum = LLVMBuildAdd(Builder, CallFibX1, CallFibX2, "addresult")
        
    ;Create the return instruction And add it To the basic block
    LLVMBuildRet(Builder, Sum)
    
    ;Don't forget to free the builder.
    LLVMDisposeBuilder(Builder)
    
    ;Return the function ref
    ProcedureReturn FibF
    
  EndProcedure

Procedure main(n)
   Protected errStr.s
   Protected EE.i
   
    LLVMLinkInJIT()
    Context = LLVMGetGlobalContext()

    ;Create a module for our function.
    M = LLVMModuleCreateWithNameInContext("test fib", Context)
    
    ;Create a pass manager optimizer for our funtions 
    PM =  LLVMCreateFunctionPassManagerForModule(M);
    ;add tail call elimination parse to it 
    ;LLVMAddTailCallEliminationPass(PM);
    LLVMInitializeFunctionPassManager(PM);
    
    ;Create the Fib function in the Module and Context
    FibF = CreateFibFunction(M, Context)
    ;Run function optimizer  
    If LLVMRunFunctionPassManager(PM,FibF);
        PrintN("Optimized Function")
    EndIf 
    LLVMFinalizeFunctionPassManager(PM)
    LLVMDisposePassManager(PM);
    
    
    ;Create JIT engine execution
   If  LLVMCreateExecutionEngineForModule(@EE, M, pStr)
     PrintN(ReadVarString(pStr))
     LLVMDisposeMessage(pStr)
     Input()
     End 
  EndIf
  
  ;read the target data 
  TD =LLVMGetExecutionEngineTargetData(EE);
  PrintN(ReadVarString(LLVMCopyStringRepOfTargetData(TD)))
   ;LLVMDisposeTargetData(TD); locks up for some reason 
  
  ;Verify module 
  PrintN("verifying module")
  If  LLVMVerifyModule(M, #LLVMPrintMessageAction,pStr)
     PrintN("Error constructing function!")
     PrintN(ReadVarString(pstr))
     LLVMDisposeMessage(pStr)
     Input()
     End
  EndIf
  
  PrintN(ReadVarString(LLVMDumpModule(M)));
  
  PrintN("OK")
  PrintN("Test module succeded")
  PrintN("Run fibonacci(" + Str(n) + ") in JIT");

  ;Call the Fibonacci function With argument n:
  Arg = LLVMCreateGenericValueOfInt(LLVMInt32Type(), n, 1)
  
  st = ElapsedMilliseconds()
  GV = LLVMRunFunction(EE, FibF, 1, @Arg)
  et = ElapsedMilliseconds() 
  ;convert the result
  PrintN("Jit Result: ")
  PrintN(Str(LLVMGenericValueToInt(GV, 1)))
  PrintN("took " + Str(et-st))
  
  ;call same in PB 
   st = ElapsedMilliseconds()
   res = fibpb(n)
   et = ElapsedMilliseconds() 
  PrintN("PB Result: ")
  PrintN(Str(res))
  PrintN("took " + Str(et-st))
  
   ;call same in PB 
   st = ElapsedMilliseconds()
   res2 = fibpb2(n)
   et = ElapsedMilliseconds() 
  PrintN("PB Result 2: ")
  PrintN(Str(res2))
  PrintN("took " + Str(et-st))
    
  
  ;Dump the jit Bitcode to file 
  LLVMWriteBitcodeToFile(M,"fib.bc");
  PrintN("")
  PrintN("Dumped bytecode to 'fib.bc'") 
  
  ;clean up
  LLVMDisposeGenericValue(Arg)
  LLVMDisposeGenericValue(GV)
  LLVMDisposeExecutionEngine(EE)
 
  
  ;Create native elf from the saved bc file
   lto = lto_module_create("fib.bc");
   gen =  lto_codegen_create();
   lto_codegen_add_module(gen,lto);
   *mem = lto_codegen_compile(gen,@length.i);
   If length
    fil = CreateFile(#PB_Any,"fib.elf")
    WriteData(fil,*mem,length) 
    CloseFile(fil)
    PrintN("")
    PrintN("Created native code to 'fib.elf'") 
  EndIf   
    
  lto_codegen_dispose(gen);
  
  
EndProcedure 

OpenConsole()
PrintN("enter the number of factors < 35")
n = Val(Input())
main(n)
PrintN("")
PrintN("Press enter to quit") 
Input()
CloseConsole()

idle
Messages : 63
Inscription : ven. 30/juil./2010 2:31

Re: llvm-2.8

Message par idle »

le problème est résolu! C'était un bug avec llvm!
une journée entière, [curse on] putain bourdelle du merede! [/curse off]

So it's good News, no?
Now I need to figure out how to handle VarArgs as parameters into functions
and then it can be plugged into the PB parser and voila the beginnings of a PB cross compiler!
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: llvm-2.8

Message par G-Rom »

Good news idle, very interesting.
Répondre