рдЗрд╕ рдЕрдиреБрд╡рд╛рджрдХ рдХреЗ рд▓рд┐рдП рдПрдХ рдмреИрдХ-рдПрдВрдб рдХреЗ рд░реВрдк рдореЗрдВ, рдЯрд╛рдЗрдореЙрдЪ рдиреЗ рдПрдХ рдмрд╛рдИрдЯреЗрдХреЛрдб рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдФрд░ рдЗрд╕ рдмрд╛рдЗрдЯреЗрдХреЛрдб рдХреЗ рд▓рд┐рдП рдПрдХ рджреБрднрд╛рд╖рд┐рдпрд╛ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдХрд┐рдпрд╛ред
рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдмреИрдХрдПрдВрдб рдХреЗ рд▓рд┐рдП рдореМрдЬреВрджрд╛ рд╕рдорд╛рдзрд╛рдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдзрд┐рдХ рдЙрдЪрд┐рдд рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣реЛрдЧрд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП llvm, рдФрд░ "рдареЛрд╕ рд╡рд╛рдХреНрдпреЛрдВ рдХреЗ рдмрд┐рдирд╛ рдЖрд▓реЛрдЪрдирд╛ рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд - рдЖрд▓реЛрдЪрдирд╛" рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рдХрд╛ рдкрд╛рд▓рди рдХрд░рддреЗ рд╣реБрдП, рдореИрдВ ll llm рдХреЗ рд╕рд╛рде рдЗрд╕ рдЫреЛрдЯреА jsk рднрд╛рд╖рд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд┐рдХрд▓реНрдк рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдХрд░рддрд╛ рд╣реВрдВред
рдпрд╣ jsk рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рджреЗрдЧрд╛? рдпрд╣ рд╕рдВрдХрд▓рди, рдЕрд░реНрдерд╛рддреН, рдкрд░рд┐рдгрд╛рдо рдПрдХ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдлрд╝рд╛рдЗрд▓ рд╣реИ рдЬреЛ рдХрд┐рд╕реА рднреА рд░рдирдЯрд╛рдЗрдо рдкрд░ рдирд┐рд░реНрднрд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдЧрдВрднреАрд░ рдЕрдиреБрдХреВрд▓рди рдХреА рд╕рдВрднрд╛рд╡рдирд╛, рдХреЛрдб рдкреНрд░реЛрдлрд╛рдЗрд▓рд┐рдВрдЧ, рдФрд░ рд╣рдо рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдмреИрдХ-рдПрдВрдб рдкреНрд░рд▓реЗрдЦрди рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ (рдЬреЛ рд░рдЦрд░рдЦрд╛рд╡ рдХреА рд╕реБрд╡рд┐рдзрд╛ рджреЗрдЧрд╛)ред
рдлреНрд░рдВрдЯ-рдПрдВрдб рдбреЗрд╡рд▓рдкрд░ рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ llvm рдХреИрд╕реЗ рдХрд╛рдо рдХрд░реЗрдЧрд╛?
рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП llvm рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдПрдХ рд╕рдВрджрд░реНрдн рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдореЙрдбреНрдпреВрд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░реЗрдВред рдкреНрд░рддреНрдпреЗрдХ рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рдХрдИ рдХрд╛рд░реНрдп рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдЪреВрдВрдХрд┐ jsk рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рд╣рдо рдПрдХ рдлрд╝рдВрдХреНрд╢рди - рдореБрдЦреНрдп () рдмрдирд╛рдПрдВрдЧреЗред
рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдХреЛрдб рдХреЗ рдХрдИ рдмреНрд▓реЙрдХ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред
рдХреЛрдб рдмреНрд▓реЙрдХ рдХреНрдпрд╛ рд╣реИ?
рдЕрдХреНрд╕рд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдПрдХ рд▓реЗрдмрд▓ рдкрд░ рдирд┐рдпрдВрддреНрд░рдг рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдкреИрджрд╛ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдЕрднреА рддрдХ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдирд╣реАрдВ рд╣реИред libjit рдЖрдкрдХреЛ рдкрд╣рд▓реЗ рдПрдХ рд▓реЗрдмрд▓ рдмрдирд╛рдиреЗ рдФрд░ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдФрд░ рдЗрд╕реЗ рдмрд╛рдж рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ, Gnu llightning рдЖрдкрдХреЛ рдХреЛрдб рдХреЛ рдирд┐рдпрдВрддреНрд░рдг рд╕реНрдерд╛рдирд╛рдиреНрддрд░рдг рд▓рд┐рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдФрд░ рдмрд╛рдж рдореЗрдВ рд╡рд╛рдВрдЫрд┐рдд рдкрддреЗ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рдХреЛрдб рдХреЛ рдкреИрдЪ рдХрд░рддрд╛ рд╣реИ, рдФрд░ llvm рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рджреГрд╖реНрдЯрд┐рдХреЛрдг - рдХреЛрдб рдмреНрд▓реЙрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред
рдпрд╣реА рд╣реИ, llvm рдПрдкреАрдЖрдИ рдПрдХ рд▓реЗрдмрд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдРрд╕реА рдмрд╛рдд рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рд╣реИред рдпрджрд┐ рдЖрдкрдХреЛ рдирд┐рдпрдВрддреНрд░рдг рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдХреЛрдб рдмреНрд▓реЙрдХ рдХрд╛ рдПрдХ рд▓рд┐рдВрдХ рдХрдорд╛рдВрдб рдХреЛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдирд┐рд░реНрдорд╛рдг рдХреЗ рд▓рд┐рдП
if then else endif
LLVM API рдореЗрдВ, рдЖрдкрдХреЛ рддрддреНрдХрд╛рд▓реАрди рд╢рд╛рдЦрд╛ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдмреНрд▓реЙрдХ рдмрдирд╛рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ, рдЕрдиреНрдп рд╢рд╛рдЦрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдХреЛрдб рдмреНрд▓реЙрдХ рдФрд░ рдЗрди рдмреНрд▓реЙрдХреЛрдВ рдХреЛ рд╕рд╢рд░реНрдд рд╢рд╛рдЦрд╛ рдХрдорд╛рдВрдб рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдХреБрдЫ рдЗрд╕ рддрд░рд╣
BasicBlock *ThenBB = BasicBlock::Create(context, "");
BasicBlock *ElseBB = BasicBlock::Create(context, "");
BasicBlock *AfterIfBB = BasicBlock::Create(context, "");
Builder.CreateCondBr(CondV, ThenBB, ElseBB);
ThenBB, ElseBB, AfterIfBB.
рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХреЛрдб рдкреАрдврд╝реА рдХреЗ рд▓рд┐рдП, IRBuilder рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╕рднреА LLVM рдХрдорд╛рдВрдб рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП (рд▓рдЧрднрдЧ рдмреЛрд▓рдиреЗ рд╡рд╛рд▓реЗ) рддрд░реАрдХреЗ рд╣реЛрддреЗ рд╣реИрдВред
рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рд╕рднреА рдХреЛрдб рдмрдирд╛рдП рдЬрд╛рдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдЧреЗ рдХреНрдпрд╛ рд╣реИ?
рдпрд╣ рд╣рдорд╛рд░реЗ рд╡рд┐рд╡реЗрдХ рдкрд░ рд╣реИред рд╣рдо рдХреЗрд╡рд▓ llvm рдореЙрдбреНрдпреВрд▓ рдХреЗ рдбрдВрдк () рдкрджреНрдзрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкрдардиреАрдп рд░реВрдк рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рдмрд╛рдпрдЯреЗрдХреЛрдб рдХреЛ рдкреНрд░рд┐рдВрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдХреЛрдб рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдЕрд░реНрдерд╛рдд, JIT рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЗ рд░реВрдк рдореЗрдВ llvm рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ), рдпрд╛, рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП рдФрд░ рдЕрдзрд┐рдХ рд╕рд╣реА рдврдВрдЧ рд╕реЗ, рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдмрд╛рдпрдЯреЗрдХреЛрдб рдХреЛ рд╕рд╣реЗрдЬреЗрдВред рдпрд╣ рд╣рдореЗрдВ рдЗрд╕ рдмрд╛рдЗрдЯ рдХреЛрдб рдХреЛ рдФрд░ рдЕрдзрд┐рдХ рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝ рдХрд░рдиреЗ рдФрд░ рдорд╛рдирдХ llvm рдЯреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдмрджрд▓рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ред
рдЗрд╕ рдкреНрд░рдХрд╛рд░,
рд▓рдХреНрд╖реНрдп рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╣реИрдВ, рдХрд╛рд░реНрдп рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд╣реИрдВ, рдХрд╛рдорд░реЗрдб рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ
рдореИрдВ рдпрд╣рд╛рдВ рд╕рднреА рдХреЛрдб рдирд╣реАрдВ рдбрд╛рд▓ рд╕рдХрддрд╛, рдЕрдЧрд░ рдХреЛрдИ рднреА рд╕реНрд░реЛрддреЛрдВ рдХреЗ рд╕рд╛рде рдЦреЗрд▓рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ, рддреЛ рд╕рдВрдЧреНрд░рд╣ рдпрд╣рд╛рдВ рдпрд╛ рдпрд╣рд╛рдВ рдЙрдкрд▓рдмреНрдз рд╣реИ ред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рд╕реНрд░реЛрдд рдкрд╛рда рдореЗрдВ рдХреБрдЫ рд╣реЗрдбрд░ рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
# рдЬрд╛рд░реА рдХрд░реЗрдВ "llvm / DerivedTypes.h"
#include "llvm / LLVMContext.h"
#include "llvm / Module.h"
#include "llvm / Analysis / Verifier.h"
#include "llvm / Support / IRBuilder.h"
#include <llvm / support / raw_ostream.h>
#include <llvm / Bitcode / ReaderWriter.h>
рдирд╛рдорд╕реНрдерд╛рди llvm рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ ;
рдЗрддрдирд╛ рдХрд╛рдлреА рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдЕрдЧрд▓рд╛, рд╣рдо рд╕рдВрджрд░реНрдн рдХреЛ рдкреНрд░рд╛рд░рдВрдн рдХрд░рддреЗ рд╣реИрдВ, рдореЙрдбреНрдпреВрд▓, рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдХреЛрдб рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдореБрдЦреНрдп рдлрд╝рдВрдХреНрд╢рди рдФрд░ IRBuilder рдмрдирд╛рддреЗ рд╣реИрдВ
рдШреЛрд╖рдгрд╛ рдореЗрдВ:
рд╕реНрдерд┐рд░ рдореЙрдбреНрдпреВрд▓ * TheModule ;
рд╕реНрдерд┐рд░ IRBuilder <> рдмрд┐рд▓реНрдбрд░ ( getGlobalContext ( ) ) ;
рдФрд░ рдХреЛрдб рдХреА рд╢реБрд░реБрдЖрдд рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:
LLVMContext & Context = getGlobalContext ( ) ;
TheModule = рдирдпрд╛ рдореЙрдбреНрдпреВрд▓ ( "jsk" , рд╕рдВрджрд░реНрдн ) ;
const рдкреНрд░рдХрд╛рд░ * voidType = рдкреНрд░рдХрд╛рд░ :: getVoidTy ( рд╕рдВрджрд░реНрдн ) ;
func_main = рдХрд╛рд╕реНрдЯ < рдлрд╝рдВрдХреНрд╢рди > ( TheModule - > getOrInsertFunction ( "рдореБрдЦреНрдп" , voidType, NULL ) ) ;
func_main - > setCallingConv ( CallingConv :: C ) ;
BasicBlock * block = BasicBlock :: Create ( getGlobalContext ( ) , "code" , func_main ) ;
рдмрд┐рд▓реНрдбрд░ред рд╕реЗрдЯрдЗрдиреНрд╕реНрдЯреНрд░реЙрдлрд╝реНрдЯ ( рдмреНрд▓реЙрдХ ) ;
рдХреЛрдб рдЬрдирд░реЗрдЯ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдЕрдкрдиреЗ рдбрдореА рдлрдВрдХреНрд╢рди рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд░рд┐рдЯ рд╢реВрдиреНрдп рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ bytecode рдХреЛ a.out.bb рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдбрдВрдк рдХрд░рддреЗ рд╣реИрдВ
рдмрд┐рд▓реНрдбрд░ред CreateRetVoid ( ) ;
std :: string ErrStr ;
raw_fd_ostream bitcode ( "a.out.bc" , ErrStr, 0 ) ;
WriteBitcodeToFile ( TheModule, bitcode ) ;
bitcodeред рдХрд░реАрдм ( ) ;
рдЕрдм рд╣рдорд╛рд░реА jsk рднрд╛рд╖рд╛ рдХреЗ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд▓рд┐рдП рдХреЛрдб рдЬрдирд░реЗрдЯ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ
рдЪрд░
рдкреНрд░рддреНрдпреЗрдХ рдЪрд░ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЕрдиреБрджреЗрд╢ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реНрдЯреИрдХ рдкрд░ рдПрдХ рд╕реНрдерд╛рди рдЖрд░рдХреНрд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ
%varname = alloca i32
рдпрд╛, рдПрдкреАрдЖрдИ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ
Builder.CreateAlloca(IntegerType::get(context,32), 0, VarName.c_str());
рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рд╕реНрдЯреИрдХ рдкрд░ рдПрдХ рдЬрдЧрд╣ рдЖрд╡рдВрдЯрд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рд╣рдо рдкрд╣рд▓реА рдмрд╛рд░ рдЪрд░ рд╕реЗ рдорд┐рд▓реЗ рдереЗред рдХреНрдпреЛрдВрдХрд┐ рдпрджрд┐ рдПрдХ рд▓реВрдк рдХреЗ рдмреАрдЪ рдореЗрдВ рдПрдХ рдЪрд░ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рд╣рдо рдЪрд░ рдХреА рдкреНрд░рддрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдкреВрд░реЗ рдвреЗрд░ рдХреЛ рдЦрд░рд╛рдм рдХрд░ рджреЗрдВрдЧреЗред
рдЗрд╕рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЪрд░ рдХреА рдПрдХ рд╕реВрдЪреА рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП, рдФрд░ рдЬрдм рд╣рдо рдкрд╛рда рдореЗрдВ рдПрдХ рдЪрд░ рдорд┐рд▓рддреЗ рд╣реИрдВ, рддреЛ рдЬрд╛рдВрдЪ рдХрд░реЗрдВ, рдФрд░ рдпрджрд┐ рдпрд╣ рдкрд╣рд▓реА рдмрд╛рд░ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдЗрд╕рдХреЗ рд▓рд┐рдП рдореЗрдореЛрд░реА рдЖрд╡рдВрдЯрди рдХреЛ рдлрд╝рдВрдХреНрд╢рди рдХреЛрдб рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рд░рдЦреЗрдВред рдпрд╣реА рд╣реИ, рд╡рд░реНрддрдорд╛рди рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рдкрд╣рд▓рд╛ рдмреНрд▓реЙрдХ рд▓реЗрдВ, рдФрд░ рдЗрд╕ рдмреНрд▓реЙрдХ рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рдПрд▓реЛрдХрд╛ рдХрдорд╛рдВрдб рдЬреЛрдбрд╝реЗрдВред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, llvm рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рдЕрдВрдд рдореЗрдВ рд╣реА рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдмреНрд▓реЙрдХ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рднреА рдХрдорд╛рдВрдб рд▓рд┐рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдпрд╣ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЖрдк рд╕реНрд░реЛрдд рдХреЛрдб рдореЗрдВ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ - CreateEntryBlockAlloca () рдлрд╝рдВрдХреНрд╢рди;
рдкрд░рд┐рд╡рд░реНрддрдирд╢реАрд▓ рдХрд╛рд░реНрдп
Value *result = value->emit();
Builder.CreateStore(result,varreference);
..
store i32 %result, i32* %varreference
рддрджрдиреБрд╕рд╛рд░, рдЪрд░ рдХрд╛ рдореВрд▓реНрдп рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ
return Builder.CreateLoad(varref);
%val = load i32* %varref
рдмрд╛рдЗрдирд░реА рдФрд░ рдпреВрдирд░реА рдСрдкрд░реЗрд╢рдиред
рдпрд╣ рдпрд╣рд╛рдБ рд╕рд░рд▓ рд╣реИ
рд╕реНрд╡рд┐рдЪ ( рдСрдк ) {
рдХреЗрд╕ '+' : рд░рд┐рдЯрд░реНрди рдмрд┐рд▓реНрдбрд░ред CreateAdd ( рдПрд▓, рдЖрд░ ) ;
рдорд╛рдорд▓рд╛ '-' : рд░рд┐рдЯрд░реНрди рдмрд┐рд▓реНрдбрд░ред рдХреНрд░рд┐рдПрдЯрд╕рдм ( рдПрд▓, рдЖрд░ ) ;
рдорд╛рдорд▓рд╛ '*' : рд░рд┐рдЯрд░реНрди рдмрд┐рд▓реНрдбрд░ред CreateMul ( L, R ) ;
рдорд╛рдорд▓рд╛ '/' : рд░рд┐рдЯрд░реНрди рдмрд┐рд▓реНрдбрд░ред CreateSDiv ( рдПрд▓, рдЖрд░ ) ;
рдорд╛рдорд▓рд╛ '<' : tmp = рдмрд┐рд▓реНрдбрд░ред CreateICmpSLT ( рдПрд▓, рдЖрд░ ) ; рд╡рд╛рдкрд╕реА рдмрд┐рд▓реНрдбрд░ред CreateZExt ( tmp, IntegerType :: get ( getGlobalContext ( ) , 32 ) ) ;
рдорд╛рдорд▓рд╛ '>' : tmp = рдмрд┐рд▓реНрдбрд░ CreateICmpSGT ( рдПрд▓, рдЖрд░ ) ; рд╡рд╛рдкрд╕реА рдмрд┐рд▓реНрдбрд░ред CreateZExt ( tmp, IntegerType :: get ( getGlobalContext ( ) , 32 ) ) ;
рдорд╛рдорд▓рд╛ 'рдПрд▓' : tmp = рдмрд┐рд▓реНрдбрд░ред CreateICmpSLE ( L, R ) ; рд╡рд╛рдкрд╕реА рдмрд┐рд▓реНрдбрд░ред CreateZExt ( tmp, IntegerType :: get ( getGlobalContext ( ) , 32 ) ) ;
рдорд╛рдорд▓рд╛ 'рдЬреА' : tmp = рдмрд┐рд▓реНрдбрд░ред CreateICmpSGE ( L, R ) ; рд╡рд╛рдкрд╕реА рдмрд┐рд▓реНрдбрд░ред CreateZExt ( tmp, IntegerType :: get ( getGlobalContext ( ) , 32 ) ) ;
рдорд╛рдорд▓рд╛ 'рдПрди' : tmp = рдмрд┐рд▓реНрдбрд░ред CreateICmpNE ( рдПрд▓, рдЖрд░ ) ; рд╡рд╛рдкрд╕реА рдмрд┐рд▓реНрдбрд░ред CreateZExt ( tmp, IntegerType :: get ( getGlobalContext ( ) , 32 ) ) ;
рдорд╛рдорд▓рд╛ '=' : tmp = рдмрд┐рд▓реНрдбрд░ред CreateICmpEQ ( рдПрд▓, рдЖрд░ ) ; рд╡рд╛рдкрд╕реА рдмрд┐рд▓реНрдбрд░ред CreateZExt ( tmp, IntegerType :: get ( getGlobalContext ( ) , 32 ) ) ;
рдбрд┐рдлрд╝реЙрд▓реНрдЯ : рддреНрд░реБрдЯрд┐ ErrorV ( "рдЕрдорд╛рдиреНрдп рдмрд╛рдЗрдирд░реА рдСрдкрд░реЗрдЯрд░" ) ;
}
рдЖрдИрдПрдл рдФрд░ WHILE
рдЬреИрд╕рд╛ рдХрд┐ рдкрд╣рд▓реЗ рд╣реА рд╡рд░реНрдгрд┐рдд рд╣реИ, рд╣рдо рдХреЛрдб рдмреНрд▓реЙрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП IF:
рдорд╛рди * CondV = cond - > emit ( ) ;
// рд╕реНрдерд┐рддрд┐ рдХреА рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреА рддреБрд▓рдирд╛ 0 рд╕реЗ рдХрд░реЗрдВ
рдХрдВрдбрд╡ = рдмрд┐рд▓реНрдбрд░ред CreateICmpNE ( CondV, рд╢реВрдиреНрдп, "ifcond" ) ;
// IF рд╢рд╛рдЦрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдмреНрд▓реЙрдХ
BasicBlock * ThenBB = BasicBlock :: Create ( getGlobalContext ( ) , "thenblock" ) ;
BasicBlock * ElseBB = BasicBlock :: Create ( getGlobalContext ( ) , "elseblock" ) ;
BasicBlock * MergeBB = BasicBlock :: рдмрдирд╛рдПрдБ ( getGlobalContext ( ) , "afterifblock" ) ;
// рджрд░рдЕрд╕рд▓ IF рдХреЗ рд▓рд┐рдП рдмреНрд░рд╛рдВрдЪрд┐рдВрдЧ
рдмрд┐рд▓реНрдбрд░ред CreateCondBr ( CondV, ThenBB, ElseBB ) ;
// рдЕрдЧрд▓рд╛, рдХреЛрдб рдХреЛ THEN рд╢рд╛рдЦрд╛ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ
рдмрд┐рд▓реНрдбрд░ред рд╕реЗрдЯрдЗрдиреНрдЯрд░рдкреЙрдЗрдВрдЯ ( рддрдмрдмреАрдмреА ) ;
рдпрд╣ - > рдлрд┐рд░ред рдЙрддреНрд╕рд░реНрдЬрди ( ) ;
// "рдХреЗ рдмрд╛рдж" рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП "рд╕реНрд╡рд┐рдЪ" рдХреЗ рдЕрдВрдд рдореЗрдВ
рдмрд┐рд▓реНрдбрд░ред CreateBr ( MergeBB ) ;
TheFunction - > getBasicBlockList ( ) ред push_back ( ElseBB ) ;
// рдЕрдЧрд▓рд╛, рдИрдПрд▓рдПрд╕рдИ рдкрд▓рдХ рдореЗрдВ рдХреЛрдб рдЬреЛрдбрд╝реЗрдВ
рдмрд┐рд▓реНрдбрд░ред рд╕реЗрдЯрдЗрдиреНрдЯрд░рдкреЙрдЗрдВрдЯ ( ElseBB ) ;
рдпрд╣ - > рдЕрдиреНрдпред рдЙрддреНрд╕рд░реНрдЬрди ( ) ;
// рдЕрдВрдд рдореЗрдВ, "рдЖрдИрдПрдл рдХреЗ рдмрд╛рдж" рдкрд░ рдЬрд╛рдПрдВ
рдмрд┐рд▓реНрдбрд░ред CreateBr ( MergeBB ) ;
TheFunction - > getBasicBlockList ( ) ред push_back ( MergeBB ) ;
// IF рдХреЗ рдмрд╛рдж, рдХреЗрд╡рд▓ MergeBB рдореЗрдВ рдХреЛрдб рдЬреЛрдбрд╝реЗрдВ
рдмрд┐рд▓реНрдбрд░ред рд╕реЗрдЯрдЗрдВрд╕реНрдЯреНрд░реЙрдлрд╝реНрдЯ ( рдорд░реНрдЬрдмреА ) ;
рд╢реВрдиреНрдп рд▓реМрдЯреЗрдВ ;
WHILE рдХреЗ рд▓рд┐рдП:
BasicBlock * CondBB = BasicBlock :: Create ( getGlobalContext ( ) , "asxpr" , TheFunction ) ;
BasicBlock * LoopBB = BasicBlock :: Create ( getGlobalContext ( ) , "рд▓реВрдк" ) ;
BasicBlock * AfterBB = BasicBlock :: Create ( getGlobalContext ( ) , "after" ) ;
рдмрд┐рд▓реНрдбрд░ред CreateBr ( CondBB ) ;
// рд╣рд╛рд▓рдд рдмреНрд▓реЙрдХред рдпрд╣рд╛рдВ рдХреЛрдб рдЬреЛрдбрд╝реЗрдВред рд╣рдо рдПрдХ рд╢рд░реНрдд рдХреЛрдб рдЙрддреНрдкрдиреНрди рдХрд░рддреЗ рд╣реИрдВ, 0 рд╕реЗ рдкрд░рд┐рдгрд╛рдо рдХреА рддреБрд▓рдирд╛ рдХрд░реЗрдВ
// рдФрд░ рдЕрдЧрд░ рд╢рд░реНрдд рдкреВрд░реА рдирд╣реАрдВ рд╣реБрдИ рд╣реИ - AfterBB рдкрд░ рдЬрд╛рдПрдВ
рдмрд┐рд▓реНрдбрд░ред рд╕реЗрдЯрдЗрдиреНрд╕реНрдЯреНрд░реЙрдлрд╝реНрдЯ ( CondBB ) ;
рдорд╛рди * CondV = cond - > emit ( ) ;
рдЕрдЧрд░ ( CondV == 0 ) рд╡рд╛рдкрд╕реА 0 ;
// 0 рдХреЗ рдмрд░рд╛рдмрд░ рдХреА рддреБрд▓рдирд╛ рдХрд░рдХреЗ рдПрдХ рдмреВрд▓ рдореЗрдВ рд╣рд╛рд▓рдд рдмрджрд▓реЗрдВред
рдХрдВрдбрд╡ = рдмрд┐рд▓реНрдбрд░ред CreateICmpNE ( рдХреЛрдВрдбрд╡реА, рд╢реВрдиреНрдп, "рд╡реНрд╣рд┐рд▓рдХреЙрдиреНрдб" ) ;
рдмрд┐рд▓реНрдбрд░ред CreateCondBr ( CondV, LoopBB, AfterBB ) ;
// рдмреЙрдбреА рдмреНрд▓реЙрдХ рдЬрдмрдХрд┐ред рд╣рдо рдпрд╣рд╛рдВ рдмреЙрдбреА рдХреЛрдб рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рдлрд┐рд░ WHILE рдХрдВрдбреАрд╢рди рдореЗрдВ рдмрджрд▓рд╛рд╡ рдХрд░рддреЗ рд╣реИрдВ
TheFunction - > getBasicBlockList ( ) ред push_back ( рд▓реВрдкрдмреА ) ;
рдмрд┐рд▓реНрдбрд░ред рд╕реЗрдЯрдЗрдиреНрд╕реНрдЯреНрд░реЙрдлрд╝реНрдЯ ( LoopBB ) ;
рдорд╛рди * рдСрдкреНрд╕ = рдпрд╣ - > рдСрдкреНрд╕ред рдЙрддреНрд╕рд░реНрдЬрди ( ) ;
рдмрд┐рд▓реНрдбрд░ред CreateBr ( CondBB ) ;
// рдмреНрд▓реЙрдХ 'рдЖрдлреНрдЯрд░ рд╡реНрд╣рд╛рдЗрд▓', рдлрд┐рд▓рд╣рд╛рд▓ рд╣рдо рдпрд╣реА рдХрд╣рддреЗ рд╣реИрдВ
// рдХрд┐ рдЗрд╕ рдмреНрд▓реЙрдХ рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рднреА рдХреЛрдб рд▓рд┐рдЦреЗ рдЬрд╛рдиреЗ рдЪрд╛рд╣рд┐рдП
TheFunction - > getBasicBlockList ( ) ред push_back ( AfterBB ) ;
рдмрд┐рд▓реНрдбрд░ред рд╕реЗрдЯрдЗрдиреНрд╕реНрдЯреНрд░реЙрдлрд╝реНрдЯ ( AfterBB ) ;
рдЕрдВрдд рдореЗрдВ, рд╣рдо рдЕрдкрдиреЗ рд╕рдВрдХрд▓рдХ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ
#make
bison -d jsk.y
flex jsk.lex
g++ -O2 jsk.tab.c lex.yy.c `llvm-config --cxxflags --libs` -lrt -ldl -o jskc
jsk.tab.c: In function 'int yyparse()':
jsk.tab.c:2026: warning: deprecated conversion from string constant to 'char*'
jsk.tab.c:2141: warning: deprecated conversion from string constant to 'char*'
jsk.lex: In function 'int yylex()':
jsk.lex:34: warning: deprecated conversion from string constant to 'char*'
jsk.lex:35: warning: deprecated conversion from string constant to 'char*'
jsk.lex:39: warning: deprecated conversion from string constant to 'char*'
So. рдХрдВрдкрд╛рдЗрд▓рд░ рддреИрдпрд╛рд░ рд╣реИред рдЖрдЗрдП рдЗрд╕реЗ рдХреБрдЫ рдкрд░реАрдХреНрд╖рдг рдХрд╛рд░реНрдп рдкрд░ рдЖрдЬрд╝рдорд╛рдПрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП
a=b=88;
b=b+1;
echo("test4=",a," ",b,"\n");
рдорд╣рд╕реВрд╕ рдХрд┐рдпрд╛ рд╣реИ:
./jskc <test3.jsk
рдФрд░ рд╣рдореЗрдВ рд╡рд░реНрддрдорд╛рди рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ a.out.bc рдорд┐рд▓рддрд╛ рд╣реИред рд╣рдо рдЗрд╕реЗ рдЕрд▓рдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
llvm-dis <aout.bc
; ModuleID = ''
@.format1 = internal constant [3 x i8] c"%d\00" ; <[3 x i8]*> [#uses=1]
@.format2 = internal constant [3 x i8] c"%s\00" ; <[3 x i8]*> [#uses=1]
@0 = internal constant [7 x i8] c"test4=\00" ; <[7 x i8]*> [#uses=1]
@1 = internal constant [2 x i8] c" \00" ; <[2 x i8]*> [#uses=1]
@2 = internal constant [2 x i8] c"\0A\00" ; <[2 x i8]*> [#uses=1]
define void @main() {
code:
%a = alloca i32 ; <i32*> [#uses=2]
%b = alloca i32 ; <i32*> [#uses=4]
%int_for_scanf___ = alloca i32 ; <i32*> [#uses=0]
store i32 88, i32* %b
store i32 88, i32* %a
%0 = load i32* %b ; [#uses=1]
%1 = add i32 %0, 1 ; [#uses=1]
store i32 %1, i32* %b
call void (i8*, ...)* @printf(i8* getelementptr inbounds ([3 x i8]* @.format2, i32 0, i32 0), i8* getelementptr inbounds ([7 x i8]* @0, i32 0, i32 0))
%2 = load i32* %a ; [#uses=1]
call void (i8*, ...)* @printf(i8* getelementptr inbounds ([3 x i8]* @.format1, i32 0, i32 0), i32 %2)
call void (i8*, ...)* @printf(i8* getelementptr inbounds ([3 x i8]* @.format2, i32 0, i32 0), i8* getelementptr inbounds ([2 x i8]* @1, i32 0, i32 0))
%3 = load i32* %b ; [#uses=1]
call void (i8*, ...)* @printf(i8* getelementptr inbounds ([3 x i8]* @.format1, i32 0, i32 0), i32 %3)
call void (i8*, ...)* @printf(i8* getelementptr inbounds ([3 x i8]* @.format2, i32 0, i32 0), i8* getelementptr inbounds ([2 x i8]* @2, i32 0, i32 0))
ret void
}
declare void @printf(i8*, ...)
declare void @scanf(i8*, ...)
declare void @exit(i32)
lli , ( ) - :
$ llvmc a.out.bc
(!) a.out, , JSK :
$ ls -al ./a.out
-rwxr-xr-x 1 walrus walrus 4639 2010-08-25 16:49 ./a.out
$ file a.out
a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
$ ldd a.out
linux-gate.so.1 => (0x00762000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00456000)
/lib/ld-linux.so.2 (0x00ee4000)
,
$ ./a.out
test4=88 89
.