llvm-2.9 hello llvm-PB world

Linux specific forum
User avatar
idle
Always Here
Always Here
Posts: 5839
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

llvm-2.9 hello llvm-PB world

Post by idle »

llvm2.9 Include. shared objects llc executable
Fibonacci JIT example
Hello LLVM_PB World

llvm2.9.zip

If you want to build it your self
Grom wrote:
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

info on llvm
http://llvm.org/
http://llvm.org/docs/LangRef.html#modulestructure
Last edited by idle on Mon Jun 20, 2011 3:51 am, edited 5 times in total.
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
idle
Always Here
Always Here
Posts: 5839
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: llvm-2.8

Post by idle »

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

Altered the Fibonacci example so it will dump the bytecode to file and then compile it to native code
(not that it'll run) but just testing the functionality.

I'm a bit confused about how your supposed to go about defining functions that have multiple parameters

Code: Select all

 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?

or just pass the address of an integer Array containing the type references?
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
idle
Always Here
Always Here
Posts: 5839
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: llvm-2.8

Post by idle »

Playing around with the Fibonaci example
It's curious from blogs and forums post I've come across from google concerning the speed of the llvm JIT
the C++ users seem to be impressed with how fast the JIT is, some reference saying it's faster than native compiled gcc.
Well as far as I can see it's nowhere near as fast as PB which is around 10x faster with the debugger on!
turn off the debugger and now PB is like 1000x faster. :mrgreen:
if you get rid of the recursion the PB fib2 function is off the charts, maybe the JIT is falling back to the interpretor?
I guess there's something not quite right the implementation, there's no way it should be so slow surely.
perhaps we're missing a configuration step somewhere, turn off slow jit, More power Scotty!

Also I may have an issue with the helper function ReadVarArg
if you create an error in the fib function building routine, the VerifyModule call will print out the errors
but it somehow manages to reverse the calls to PrintN and zeros the pointer to the Char **
that's enough confuse a cat for a day I think!

*note changed the header file
llvm2.8.zip

Code: Select all

;  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 
 If *chr
 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. 
    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!")   ;< if theres and error in the module 
     PrintN(ReadVarString(pstr))               ;   it prints the Error info before "Error constructing function" ?    
     LLVMDisposeMessage(pStr)
     Input()
     End
  EndIf

  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()

Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
idle
Always Here
Always Here
Posts: 5839
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: llvm-2.8

Post by idle »

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: Select all

 
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
}


Also there is some really strange interaction when llvm generates and error message
it causes a double call so you end up with an IMA as the pointer is either 0 or the offset on the second call
obviously there's something wrong with the way it's being handled but I can't think of how to fix it

The dirty code

Code: Select all

;  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 ;dirty but *chr gets nuked to 0 or ct offest
 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()


Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
idle
Always Here
Always Here
Posts: 5839
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: llvm-2.8

Post by idle »

That was a real shiter, spent 3/4 of the day trying to work out what the hell was going on
turns out it's just a bug in llvm itself. Simply adding a Pass Manager to optimize the function
solved the issues.

You don't really want to be creating the code in SSA form yourself phi nodes will do your head in

Code: Select all

define fastcc i32 @fib2(i32 %ArgX) {
EntryBlock:
  %cond = icmp slt i32 %ArgX, 3
  br i1 %cond, label %IF, label %Else

IF:                                               ; preds = %EntryBlock
  ret i32 1

Else:                                             ; preds = %EntryBlock, %while
  %D.0 = phi i32 [ %sub, %while ], [ %ArgX, %EntryBlock ]
  %C.0 = phi i32 [ %addab, %while ], [ 0, %EntryBlock ]
  %B.0 = phi i32 [ %A.0, %while ], [ 1, %EntryBlock ]
  %A.0 = phi i32 [ %addab, %while ], [ 1, %EntryBlock ]
  %cond1 = icmp sgt i32 %D.0, 2
  br i1 %cond1, label %while, label %ewhile

while:                                            ; preds = %Else
  %addab = add i32 %A.0, %B.0
  %sub = add i32 %D.0, -1
  br label %Else

ewhile:                                           ; preds = %Else
  ret i32 %C.0
}

Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
idle
Always Here
Always Here
Posts: 5839
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: llvm-2.9

Post by idle »

updated to llvm-2.9 included the shared objects in the zip (32 bit)

llvm2.9.zip

If you want to build it your self
Grom wrote:
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
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
idle
Always Here
Always Here
Posts: 5839
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: llvm-2.9 hello llvm-PB world

Post by idle »

The 2nd milestone

Hello LLVM-PB world :mrgreen:

As long as you've got GCC it should work
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
idle
Always Here
Always Here
Posts: 5839
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: llvm-2.9 hello llvm-PB world

Post by idle »

Added example of passing in multiple parameters into a function.
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
idle
Always Here
Always Here
Posts: 5839
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: llvm-2.9 hello llvm-PB world

Post by idle »

The code gen wrapper is progressing

The test code to build an Iterative Fibonacci as it would be called from a parser
The trick is to use a token and op stack to handle the variable mutation.
No Phi nodes required :mrgreen:

Code: Select all

;   Procedure.q fibPB2(argx.q) ;itterative fib fast   
;   Protected a.q,b.q,c.q
;   a=1:b=1:c=0
;   If argx <= 2
;     ProcedureReturn 1
;   Else 
;     While argx > 2
;       c = a + b
;       b = a
;       a = c
;       argx-1
;     Wend
;     ProcedureReturn c
;  EndIf    
; EndProcedure

  NewFunction("fib",#QuadType)   
  AddFunctionParam("fib",argx)
  DeclareFunction(Context,Module,"fib")     
  CreateFunction(Context,Module,"fib")     
  AddFunctionProtectedVar("fib",aa)
  AddFunctionProtectedVar("fib",bb)
  AddFunctionProtectedVar("fib",cc)
  AddFunctionCmp("fib",#LLVMIntSLE,argx,p4)
  AddFunctionReturn("fib",p5)
  AddFunctionElse("fib")
  AddFunctionWhile("fib",#LLVMIntSGT,argX,p6)
  push(lexp(),aa)
  push(ops(),#LLVMAdd)     
  push(lexp(),bb)
  push(ops(),#LLVMAssign)
  push(lexp(),cc)
  Expr()                   ;c = a + b     
  push(lexp(),bb)
  push(ops(),#LLVMAssign)
  push(lexp(),aa)
  Expr()                  ;b = a
  push(lexp(),aa)
  push(ops(),#LLVMAssign)
  push(lexp(),cc)   
  expr()                 ;a = c 
  push(lexp(),argX)
  push(ops(),#LLVMsub)
  push(lexp(),one)
  push(lexp(),argX)
  push(ops(),#LLVMAssign)
  expr()               ; Argx - 1     
  AddfunctionWend("fib")
  AddFunctionReturn("fib",cc)
 
Windows 11, Manjaro, Raspberry Pi OS
Image
eesau
Enthusiast
Enthusiast
Posts: 589
Joined: Fri Apr 27, 2007 12:38 pm
Location: Finland

Re: llvm-2.9 hello llvm-PB world

Post by eesau »

Thanks for your efforts idle, this is all very interesting! I'll play around with the code samples once I get the chance to.

How's working with LLVM by the way, any opinions now that you've tried it?
User avatar
idle
Always Here
Always Here
Posts: 5839
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: llvm-2.9 hello llvm-PB world

Post by idle »

LLVM is great, though the C interface is a bit fiddly but it's fairly intuitive once you've got past the introduction.
While there's no documentation for the c interface, it's pretty much a case of trial and error.
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
idle
Always Here
Always Here
Posts: 5839
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: llvm-2.9 hello llvm-PB world

Post by idle »

Code Generation wrapper progress

[done]
types (all PB primitive types including constant strings)
variables
constants
binary operations
If,Else,ElseIf
For While Repeat (forever/until) : Break, Continue
Procedures
Imports
Function calls
Type casting
Select
Arrays
structures
pointer operations
[/done]

[todo]
Memory ...peek poke
strings
[/todo]
Last edited by idle on Thu Jul 14, 2011 4:26 am, edited 3 times in total.
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
DoubleDutch
Addict
Addict
Posts: 3220
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Re: llvm-2.9 hello llvm-PB world

Post by DoubleDutch »

Wow, you're doing great so far. :)
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
User avatar
idle
Always Here
Always Here
Posts: 5839
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: llvm-2.9 hello llvm-PB world

Post by idle »

Thanks, it's getting there, hopefully I can figure out the pointer operations this weekend so I can get arrays and structures working
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
idle
Always Here
Always Here
Posts: 5839
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: llvm-2.9 hello llvm-PB world

Post by idle »

time to wire the code generator into the PB parser
Debugging ... ...
Windows 11, Manjaro, Raspberry Pi OS
Image
Post Reply