Skip to content

Instantly share code, notes, and snippets.

@jiayuasu
Forked from alloy/README.markdown
Created July 26, 2018 20:22
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jiayuasu/9c0ad875b403b75bde5585ce847bc307 to your computer and use it in GitHub Desktop.
Save jiayuasu/9c0ad875b403b75bde5585ce847bc307 to your computer and use it in GitHub Desktop.
Learn the LLVM C++ API by example.

The easiest way to start using the LLVM C++ API by example is to have LLVM generate the API usage for a given code sample. In this example it will emit the code required to rebuild the test.c sample by using LLVM:

$ clang -c -emit-llvm test.c -o test.ll
$ llc -march=cpp test.ll -o test.cpp
#include <stdio.h>
int some_function(int input)
{
return input * 2;
}
int main()
{
int answer = some_function(21);
printf("Answer is %d\n", answer);
return 0;
}
// Generated by llvm2cpp - DO NOT MODIFY!
#include <llvm/Pass.h>
#include <llvm/PassManager.h>
#include <llvm/ADT/SmallVector.h>
#include <llvm/Analysis/Verifier.h>
#include <llvm/Assembly/PrintModulePass.h>
#include <llvm/IR/BasicBlock.h>
#include <llvm/IR/CallingConv.h>
#include <llvm/IR/Constants.h>
#include <llvm/IR/DerivedTypes.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/GlobalVariable.h>
#include <llvm/IR/InlineAsm.h>
#include <llvm/IR/Instructions.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <llvm/Support/FormattedStream.h>
#include <llvm/Support/MathExtras.h>
#include <algorithm>
using namespace llvm;
Module* makeLLVMModule();
int main(int argc, char**argv) {
Module* Mod = makeLLVMModule();
verifyModule(*Mod, PrintMessageAction);
PassManager PM;
PM.add(createPrintModulePass(&outs()));
PM.run(*Mod);
return 0;
}
Module* makeLLVMModule() {
// Module Construction
Module* mod = new Module("test.ll", getGlobalContext());
mod->setDataLayout("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128");
mod->setTargetTriple("x86_64-apple-macosx10.10.0");
// Type Definitions
ArrayType* ArrayTy_0 = ArrayType::get(IntegerType::get(mod->getContext(), 8), 14);
PointerType* PointerTy_1 = PointerType::get(ArrayTy_0, 0);
std::vector<Type*>FuncTy_2_args;
FuncTy_2_args.push_back(IntegerType::get(mod->getContext(), 32));
FunctionType* FuncTy_2 = FunctionType::get(
/*Result=*/IntegerType::get(mod->getContext(), 32),
/*Params=*/FuncTy_2_args,
/*isVarArg=*/false);
PointerType* PointerTy_3 = PointerType::get(IntegerType::get(mod->getContext(), 32), 0);
std::vector<Type*>FuncTy_4_args;
FunctionType* FuncTy_4 = FunctionType::get(
/*Result=*/IntegerType::get(mod->getContext(), 32),
/*Params=*/FuncTy_4_args,
/*isVarArg=*/false);
PointerType* PointerTy_5 = PointerType::get(FuncTy_2, 0);
PointerType* PointerTy_6 = PointerType::get(IntegerType::get(mod->getContext(), 8), 0);
std::vector<Type*>FuncTy_8_args;
FuncTy_8_args.push_back(PointerTy_6);
FunctionType* FuncTy_8 = FunctionType::get(
/*Result=*/IntegerType::get(mod->getContext(), 32),
/*Params=*/FuncTy_8_args,
/*isVarArg=*/true);
PointerType* PointerTy_7 = PointerType::get(FuncTy_8, 0);
// Function Declarations
Function* func_some_function = mod->getFunction("some_function");
if (!func_some_function) {
func_some_function = Function::Create(
/*Type=*/FuncTy_2,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"some_function", mod);
func_some_function->setCallingConv(CallingConv::C);
}
AttributeSet func_some_function_PAL;
{
SmallVector<AttributeSet, 4> Attrs;
AttributeSet PAS;
{
AttrBuilder B;
B.addAttribute(Attribute::NoUnwind);
B.addAttribute(Attribute::StackProtect);
B.addAttribute(Attribute::UWTable);
PAS = AttributeSet::get(mod->getContext(), ~0U, B);
}
Attrs.push_back(PAS);
func_some_function_PAL = AttributeSet::get(mod->getContext(), Attrs);
}
func_some_function->setAttributes(func_some_function_PAL);
Function* func_main = mod->getFunction("main");
if (!func_main) {
func_main = Function::Create(
/*Type=*/FuncTy_4,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"main", mod);
func_main->setCallingConv(CallingConv::C);
}
AttributeSet func_main_PAL;
{
SmallVector<AttributeSet, 4> Attrs;
AttributeSet PAS;
{
AttrBuilder B;
B.addAttribute(Attribute::NoUnwind);
B.addAttribute(Attribute::StackProtect);
B.addAttribute(Attribute::UWTable);
PAS = AttributeSet::get(mod->getContext(), ~0U, B);
}
Attrs.push_back(PAS);
func_main_PAL = AttributeSet::get(mod->getContext(), Attrs);
}
func_main->setAttributes(func_main_PAL);
Function* func_printf = mod->getFunction("printf");
if (!func_printf) {
func_printf = Function::Create(
/*Type=*/FuncTy_8,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"printf", mod); // (external, no body)
func_printf->setCallingConv(CallingConv::C);
}
AttributeSet func_printf_PAL;
{
SmallVector<AttributeSet, 4> Attrs;
AttributeSet PAS;
{
AttrBuilder B;
PAS = AttributeSet::get(mod->getContext(), ~0U, B);
}
Attrs.push_back(PAS);
func_printf_PAL = AttributeSet::get(mod->getContext(), Attrs);
}
func_printf->setAttributes(func_printf_PAL);
// Global Variable Declarations
GlobalVariable* gvar_array__str = new GlobalVariable(/*Module=*/*mod,
/*Type=*/ArrayTy_0,
/*isConstant=*/true,
/*Linkage=*/GlobalValue::PrivateLinkage,
/*Initializer=*/0, // has initializer, specified below
/*Name=*/".str");
gvar_array__str->setAlignment(1);
// Constant Definitions
Constant *const_array_9 = ConstantDataArray::getString(mod->getContext(), "Answer is %d\x0A", true);
ConstantInt* const_int32_10 = ConstantInt::get(mod->getContext(), APInt(32, StringRef("1"), 10));
ConstantInt* const_int32_11 = ConstantInt::get(mod->getContext(), APInt(32, StringRef("2"), 10));
ConstantInt* const_int32_12 = ConstantInt::get(mod->getContext(), APInt(32, StringRef("0"), 10));
ConstantInt* const_int32_13 = ConstantInt::get(mod->getContext(), APInt(32, StringRef("21"), 10));
std::vector<Constant*> const_ptr_14_indices;
const_ptr_14_indices.push_back(const_int32_12);
const_ptr_14_indices.push_back(const_int32_12);
Constant* const_ptr_14 = ConstantExpr::getGetElementPtr(gvar_array__str, const_ptr_14_indices);
// Global Variable Definitions
gvar_array__str->setInitializer(const_array_9);
// Function Definitions
// Function: some_function (func_some_function)
{
Function::arg_iterator args = func_some_function->arg_begin();
Value* int32_input = args++;
int32_input->setName("input");
BasicBlock* label_entry = BasicBlock::Create(mod->getContext(), "entry",func_some_function,0);
// Block entry (label_entry)
AllocaInst* ptr_input_addr = new AllocaInst(IntegerType::get(mod->getContext(), 32), "input.addr", label_entry);
ptr_input_addr->setAlignment(4);
StoreInst* void_15 = new StoreInst(int32_input, ptr_input_addr, false, label_entry);
void_15->setAlignment(4);
LoadInst* int32_16 = new LoadInst(ptr_input_addr, "", false, label_entry);
int32_16->setAlignment(4);
BinaryOperator* int32_mul = BinaryOperator::Create(Instruction::Mul, int32_16, const_int32_11, "mul", label_entry);
ReturnInst::Create(mod->getContext(), int32_mul, label_entry);
}
// Function: main (func_main)
{
BasicBlock* label_entry_18 = BasicBlock::Create(mod->getContext(), "entry",func_main,0);
// Block entry (label_entry_18)
AllocaInst* ptr_retval = new AllocaInst(IntegerType::get(mod->getContext(), 32), "retval", label_entry_18);
ptr_retval->setAlignment(4);
AllocaInst* ptr_answer = new AllocaInst(IntegerType::get(mod->getContext(), 32), "answer", label_entry_18);
ptr_answer->setAlignment(4);
StoreInst* void_19 = new StoreInst(const_int32_12, ptr_retval, false, label_entry_18);
CallInst* int32_call = CallInst::Create(func_some_function, const_int32_13, "call", label_entry_18);
int32_call->setCallingConv(CallingConv::C);
int32_call->setTailCall(false);
AttributeSet int32_call_PAL;
int32_call->setAttributes(int32_call_PAL);
StoreInst* void_20 = new StoreInst(int32_call, ptr_answer, false, label_entry_18);
void_20->setAlignment(4);
LoadInst* int32_21 = new LoadInst(ptr_answer, "", false, label_entry_18);
int32_21->setAlignment(4);
std::vector<Value*> int32_call1_params;
int32_call1_params.push_back(const_ptr_14);
int32_call1_params.push_back(int32_21);
CallInst* int32_call1 = CallInst::Create(func_printf, int32_call1_params, "call1", label_entry_18);
int32_call1->setCallingConv(CallingConv::C);
int32_call1->setTailCall(false);
AttributeSet int32_call1_PAL;
int32_call1->setAttributes(int32_call1_PAL);
ReturnInst::Create(mod->getContext(), const_int32_12, label_entry_18);
}
return mod;
}
@arpitguptagithub
Copy link

I am getting an error of invalid target

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment