Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <llvm/IR/Module.h>
- #include <llvm/IR/LLVMContext.h>
- #include <llvm/IR/IRBuilder.h>
- #include <llvm/Support/raw_ostream.h>
- #include <iostream>
- #include <list>
- #include <string>
- // compile using:
- // g++ -std=c++17 -o if-test if-test.cpp \
- // -L/opt/llvm/lib -Wl,-rpath,/opt/llvm/lib \
- // -lLLVM
- // But if your libLLVM.so is already in /usr/lib,
- // then there's no need for the rpath above
- using namespace llvm;
- int main(int argc, char** argv)
- {
- LLVMContext context;
- Module* m = new Module("if_cond.bas", context);
- Function* fmain = Function::Create(
- FunctionType::get(Type::getInt32Ty(context), ArrayRef<Type*>(Type::getInt32Ty(context)), false),
- Function::ExternalLinkage,
- "main", m);
- BasicBlock* entry = BasicBlock::Create(context, "entry", fmain);
- // Lets test a simple If like so:
- // If argc < 2 Then
- // appArg = 0
- // Else
- // appArg = argc - 1
- // EndIf
- //
- // It can be created using 2 ways:
- //
- // BranchInst* CreateBr(BasicBlock* dest);
- // or
- // BranchInst* CreateCondBr(Value* cond, BasicBlock* trueBlock, BasicBlock* falseBlock);
- //
- // The parameter above needs a name, give it 'argc'
- Argument* pArg = fmain->arg_begin();
- pArg->setName("argc");
- IRBuilder<> builder(entry);
- // Dim appArg As Integer
- AllocaInst* appArg = builder.CreateAlloca(builder.getInt32Ty(), 0, "appArg");
- //////////////////////
- // If argc < 2 Then
- //////////////////////
- Value* condition = builder.CreateICmpSLT(pArg,
- builder.getInt32(2));
- // condition is (argc < 2)
- BasicBlock* brTrue = BasicBlock::Create(context, "if_true", fmain);
- BasicBlock* brFalse = BasicBlock::Create(context, "if_false", fmain);
- BasicBlock* exit_branch = BasicBlock::Create(context, "bail", fmain);
- Value* branch_label = builder.CreateCondBr(condition, brTrue, brFalse);
- /////////////////////////
- // First, if_true branch
- /////////////////////////
- builder.SetInsertPoint(brTrue);
- // appArg = 0
- builder.CreateStore(builder.getInt32(0), appArg);
- // jump to bail
- builder.CreateBr(exit_branch);
- ///////////////////////////
- // Second, if_false branch
- ///////////////////////////
- builder.SetInsertPoint(brFalse);
- Value* argValue = pArg;
- if (AllocaInst::classof(pArg))
- {
- argValue = builder.CreateLoad(pArg);
- }
- // argc - 1
- Value* nValue = builder.CreateSub(argValue, builder.getInt32(1));
- builder.CreateStore(nValue, appArg);
- // bail
- builder.CreateBr(exit_branch);
- // The last one, implement 'bail' branch
- builder.SetInsertPoint(exit_branch);
- // before we bail, lets echo some output here
- Constant* fprinter = m->getOrInsertFunction("printf",
- FunctionType::get(builder.getInt32Ty(), ArrayRef<Type*>(builder.getInt8PtrTy()), true));
- Value* strVal = builder.CreateGlobalStringPtr("argument count => %i\n");
- Value* finalValue = builder.CreateLoad(appArg);
- Value* pp[] = { strVal, finalValue };
- builder.CreateCall(fprinter, ArrayRef<Value*>(pp));
- builder.CreateRet(builder.getInt32(0));
- std::string buff;
- raw_string_ostream rso(buff);
- m->print(rso, nullptr);
- delete m;
- std::cout << buff << "\n";
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement