您好,登錄后才能下訂單哦!
本篇文章為大家展示了LLVM IR字符串類型拼接方法是怎樣的,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
IR語義為將字符串與整型進行拼接操作;方法雖然笨拙,但能夠滿足目前的業務需求,今分享出來供大家交流與參考。代碼運行環境為LLVM6.0。 關鍵字:LLVM、字符串、char*、string、拼接 、concat、IR
#include "llvm/IR/IRBuilder.h" #include "llvm/IR/Verifier.h" #include "llvm/Support/TargetSelect.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/Function.h" #include "llvm/IR/BasicBlock.h" #include "llvm/ExecutionEngine/MCJIT.h" #include "llvm/IR/TypeBuilder.h" #include <iostream> #include <algorithm> #include <cassert> #include <cctype> #include <cstdint> #include <cstdio> #include <cstdlib> #include <map> #include <memory> #include <string> #include <vector> using namespace llvm; using namespace std; //字符串拼接操作放在C++端進行 char* javaMethodAdd( int x, char * str) { cout << "arg x:"<< x << endl; string str1 = str; string xstr = to_string(x); str1+= xstr; char *st1 = const_cast<char *>(str1.c_str()) ; return st1; } int main() { llvm::LLVMContext *context = new llvm::LLVMContext(); llvm::Module *module = new llvm::Module("test", *context); std::vector<llvm::Type *> arg_types = { llvm::Type::getInt32Ty(*context), llvm::Type::getInt32Ty(*context)}; //函數參數,返回類型為char指針 llvm::FunctionType *ftype = llvm::FunctionType::get( llvm::Type::getInt8PtrTy(*context), arg_types,false); llvm::Function *func = llvm::Function::Create( ftype, llvm::GlobalValue::LinkageTypes::ExternalLinkage, "my_func", module); func->setCallingConv(llvm::CallingConv::C); llvm::BasicBlock *bb = llvm::BasicBlock::(*context, "entry", func); llvm::IRBuilder<> builder(*context); builder.SetInsertPoint(bb); //獲取傳入的參數 llvm::Argument *arg0 = func->arg_begin() + 0; llvm::Argument *arg1 = func->arg_begin() + 1; //string begain------------------ //LLVM字符串常量 Constant *const_array_str = ConstantDataArray::getString(*context, "beeeeegineeee", false); //申請內存空間 AllocaInst* const_array_addr = builder.CreateAlloca(const_array_str->getType(), ConstantExpr::getSizeOf(const_array_str->getType()),"temaddr"); const_array_addr->setAlignment (1); std::vector<Value*> index_vector; index_vector.push_back(ConstantInt::get(Type::getInt32Ty(*context), 0)); auto valueAsPtr = builder.CreateGEP(const_array_addr, index_vector, "tmp"); // 存儲字符串到內存空間 StoreInst *sist = builder.CreateStore(const_array_str, valueAsPtr); sist->setAlignment (1); index_vector.push_back(ConstantInt::get(Type::getInt64Ty(*context), 0)); //創建指向字符串存儲內存空間的指針 auto retRes = builder.CreateInBoundsGEP( const_array_str->getType(), const_array_addr, index_vector, "tmpstr"); //string end--------------------------- //llvm::Value *result = builder.CreateAdd(arg0, arg1, "result"); llvm::Value* result = builder.CreateBinOp(llvm::Instruction::Add, arg0, arg1, "result"); //忽略函數名稱(可改為任意的) FunctionType* double_add_double_type = TypeBuilder<char*(int,char*), false>::get(*context); Function* fdouble_add_double = cast<Function>(module->getOrInsertFunction("double_add_double", double_add_double_type)); std::vector<llvm::Value*> args; args.push_back(result); args.push_back(retRes); Value* ret = builder.CreateCall(fdouble_add_double, args); builder.CreateRet(ret); llvm::InitializeNativeTarget(); llvm::InitializeNativeTargetAsmPrinter(); llvm::InitializeNativeTargetAsmParser(); //創建執行引擎 llvm::ExecutionEngine *ee = llvm::EngineBuilder(std::unique_ptr<llvm::Module>(module)).setEngineKind(llvm::EngineKind::JIT).create(); printf("executed .........segment........\n"); //LLVM函數與C++函數映射 ee->addGlobalMapping(fdouble_add_double, (char*)javaMethodAdd); ee->finalizeObject(); char* (*add)(int, int) = (char* (*)(int, int))ee->getFunctionAddress("my_func"); printf("Result: %s\n", add(43, 10)); return 0; }
//編譯和運行命令(Linux)。
// clang++ -O3 cppName.cpp -o test.bc `llvm-config --cflags --ldflags
llvm-config --libs
llvm-config --system-libs `
// ./test.bc
上述內容就是LLVM IR字符串類型拼接方法是怎樣的,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。