рд╕рдВрдХрд▓рдиред 5 рдФрд░ 1/2: рдмреИрдХ-рдПрдВрдб рдХреЗ рд░реВрдк рдореЗрдВ llvm

Tyomitch "рд╕рдВрдХрд▓рди" ( рдпрд╣рд╛рдБ , рдпрд╣рд╛рдБ , рдпрд╣рд╛рдБ , рдпрд╣рд╛рдБ , рдпрд╣рд╛рдБ рдФрд░ рдпрд╣рд╛рдБ ), рдХреЗ рд▓реЗрдЦреЛрдВ рдХреА рдПрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдореЗрдВ 4 рднрд╛рдЧреЛрдВ рдореЗрдВ рд╡рд░реНрдгрд┐рдд jsk рдЦрд┐рд▓реМрдирд╛ рднрд╛рд╖рд╛ рдХреЗ рдЕрдиреБрд╡рд╛рджрдХ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ ред

рдЗрд╕ рдЕрдиреБрд╡рд╛рджрдХ рдХреЗ рд▓рд┐рдП рдПрдХ рдмреИрдХ-рдПрдВрдб рдХреЗ рд░реВрдк рдореЗрдВ, рдЯрд╛рдЗрдореЙрдЪ рдиреЗ рдПрдХ рдмрд╛рдИрдЯреЗрдХреЛрдб рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдФрд░ рдЗрд╕ рдмрд╛рдЗрдЯреЗрдХреЛрдб рдХреЗ рд▓рд┐рдП рдПрдХ рджреБрднрд╛рд╖рд┐рдпрд╛ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдХрд┐рдпрд╛ред



рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдмреИрдХрдПрдВрдб рдХреЗ рд▓рд┐рдП рдореМрдЬреВрджрд╛ рд╕рдорд╛рдзрд╛рдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдзрд┐рдХ рдЙрдЪрд┐рдд рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣реЛрдЧрд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП 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









.







All Articles