commit a8665b2ef3199e82fd2ad076c1f07f1af2ec9272 Author: Viktor Malik Date: Mon Oct 10 14:26:38 2022 +0200 IR builder: get rid of getPointerElementType calls Usage of Value::getPointerElementType is deprecated and will be dropped in LLVM 16 [1]. There are several places where we use this method: - function (value) calls - the called function type is usually available, so just pass it to createCall, the only exception is CreateProbeReadStr which must have been refactored - getting the type of alloca instruction - there is a dedicated AllocaInst::getAllocatedType method that can be used instead - strncmp - pass sizes of the strings to CreateStrncmp to be able to get the correct string type (which is array of uint8) [1] https://llvm.org/docs/OpaquePointers.html diff --git a/src/ast/irbuilderbpf.cpp b/src/ast/irbuilderbpf.cpp index 09ae1c5e..da120ba1 100644 --- a/src/ast/irbuilderbpf.cpp +++ b/src/ast/irbuilderbpf.cpp @@ -291,17 +291,16 @@ CallInst *IRBuilderBPF::CreateHelperCall(libbpf::bpf_func_id func_id, Constant *helper_func = ConstantExpr::getCast(Instruction::IntToPtr, getInt64(func_id), helper_ptr_type); - return createCall(helper_func, args, Name); + return createCall(helper_type, helper_func, args, Name); } -CallInst *IRBuilderBPF::createCall(Value *callee, +CallInst *IRBuilderBPF::createCall(FunctionType *callee_type, + Value *callee, ArrayRef args, const Twine &Name) { #if LLVM_VERSION_MAJOR >= 11 - auto *calleePtrType = cast(callee->getType()); - auto *calleeType = cast(calleePtrType->getPointerElementType()); - return CreateCall(calleeType, callee, args, Name); + return CreateCall(callee_type, callee, args, Name); #else return CreateCall(callee, args, Name); #endif @@ -310,7 +309,7 @@ CallInst *IRBuilderBPF::createCall(Value *callee, CallInst *IRBuilderBPF::CreateBpfPseudoCallId(int mapid) { Function *pseudo_func = module_.getFunction("llvm.bpf.pseudo"); - return createCall(pseudo_func, + return CreateCall(pseudo_func, { getInt64(BPF_PSEUDO_MAP_FD), getInt64(mapid) }, "pseudo"); } @@ -349,7 +348,8 @@ CallInst *IRBuilderBPF::createMapLookup(int mapid, Value *key) Instruction::IntToPtr, getInt64(libbpf::BPF_FUNC_map_lookup_elem), lookup_func_ptr_type); - return createCall(lookup_func, { map_ptr, key }, "lookup_elem"); + return createCall( + lookup_func_type, lookup_func, { map_ptr, key }, "lookup_elem"); } CallInst *IRBuilderBPF::CreateGetJoinMap(Value *ctx, const location &loc) @@ -400,8 +400,7 @@ Value *IRBuilderBPF::CreateMapLookupElem(Value *ctx, CREATE_MEMCPY(value, call, type.GetSize(), 1); else { - assert(value->getType()->isPointerTy() && - (value->getType()->getPointerElementType() == getInt64Ty())); + assert(value->getAllocatedType() == getInt64Ty()); // createMapLookup returns an u8* auto *cast = CreatePointerCast(call, value->getType(), "cast"); CreateStore(CreateLoad(getInt64Ty(), cast), value); @@ -451,7 +450,8 @@ void IRBuilderBPF::CreateMapUpdateElem(Value *ctx, Instruction::IntToPtr, getInt64(libbpf::BPF_FUNC_map_update_elem), update_func_ptr_type); - CallInst *call = createCall(update_func, + CallInst *call = createCall(update_func_type, + update_func, { map_ptr, key, val, flags }, "update_elem"); CreateHelperErrorCond(ctx, call, libbpf::BPF_FUNC_map_update_elem, loc); @@ -475,7 +475,8 @@ void IRBuilderBPF::CreateMapDeleteElem(Value *ctx, Instruction::IntToPtr, getInt64(libbpf::BPF_FUNC_map_delete_elem), delete_func_ptr_type); - CallInst *call = createCall(delete_func, { map_ptr, key }, "delete_elem"); + CallInst *call = createCall( + delete_func_type, delete_func, { map_ptr, key }, "delete_elem"); CreateHelperErrorCond(ctx, call, libbpf::BPF_FUNC_map_delete_elem, loc); } @@ -501,72 +502,53 @@ void IRBuilderBPF::CreateProbeRead(Value *ctx, Constant *proberead_func = ConstantExpr::getCast(Instruction::IntToPtr, getInt64(read_fn), proberead_func_ptr_type); - CallInst *call = createCall(proberead_func, + CallInst *call = createCall(proberead_func_type, + proberead_func, { dst, size, src }, probeReadHelperName(read_fn)); CreateHelperErrorCond(ctx, call, read_fn, loc); } -Constant *IRBuilderBPF::createProbeReadStrFn(llvm::Type *dst, - llvm::Type *src, - AddrSpace as) -{ - assert(src && (src->isIntegerTy() || src->isPointerTy())); - // int bpf_probe_read_str(void *dst, int size, const void *unsafe_ptr) - FunctionType *probereadstr_func_type = FunctionType::get( - getInt64Ty(), { dst, getInt32Ty(), src }, false); - PointerType *probereadstr_func_ptr_type = PointerType::get( - probereadstr_func_type, 0); - return ConstantExpr::getCast(Instruction::IntToPtr, - getInt64(selectProbeReadHelper(as, true)), - probereadstr_func_ptr_type); -} - CallInst *IRBuilderBPF::CreateProbeReadStr(Value *ctx, - AllocaInst *dst, + Value *dst, size_t size, Value *src, AddrSpace as, const location &loc) { - assert(ctx && ctx->getType() == getInt8PtrTy()); return CreateProbeReadStr(ctx, dst, getInt32(size), src, as, loc); } CallInst *IRBuilderBPF::CreateProbeReadStr(Value *ctx, Value *dst, - size_t size, - Value *src, - AddrSpace as, - const location &loc) -{ - assert(ctx && ctx->getType() == getInt8PtrTy()); - Constant *fn = createProbeReadStrFn(dst->getType(), src->getType(), as); - auto read_fn = selectProbeReadHelper(as, true); - CallInst *call = createCall(fn, - { dst, getInt32(size), src }, - probeReadHelperName(read_fn)); - CreateHelperErrorCond(ctx, call, read_fn, loc); - return call; -} - -CallInst *IRBuilderBPF::CreateProbeReadStr(Value *ctx, - AllocaInst *dst, llvm::Value *size, Value *src, AddrSpace as, const location &loc) { assert(ctx && ctx->getType() == getInt8PtrTy()); - assert(dst && dst->getAllocatedType()->isArrayTy() && - dst->getAllocatedType()->getArrayElementType() == getInt8Ty()); assert(size && size->getType()->isIntegerTy()); + if (auto *dst_alloca = dyn_cast(dst)) + { + assert(dst_alloca->getAllocatedType()->isArrayTy() && + dst_alloca->getAllocatedType()->getArrayElementType() == + getInt8Ty()); + } - auto *size_i32 = CreateIntCast(size, getInt32Ty(), false); + auto *size_i32 = size; + if (size_i32->getType()->getScalarSizeInBits() != 32) + size_i32 = CreateIntCast(size_i32, getInt32Ty(), false); - Constant *fn = createProbeReadStrFn(dst->getType(), src->getType(), as); auto read_fn = selectProbeReadHelper(as, true); - CallInst *call = createCall(fn, + // int bpf_probe_read_str(void *dst, int size, const void *unsafe_ptr) + FunctionType *probereadstr_func_type = FunctionType::get( + getInt64Ty(), { dst->getType(), getInt32Ty(), src->getType() }, false); + PointerType *probereadstr_func_ptr_type = PointerType::get( + probereadstr_func_type, 0); + Constant *probereadstr_callee = ConstantExpr::getCast( + Instruction::IntToPtr, getInt64(read_fn), probereadstr_func_ptr_type); + CallInst *call = createCall(probereadstr_func_type, + probereadstr_callee, { dst, size_i32, src }, probeReadHelperName(read_fn)); CreateHelperErrorCond(ctx, call, read_fn, loc); @@ -725,8 +707,10 @@ Value *IRBuilderBPF::CreateUSDTReadArgument(Value *ctx, return result; } -Value *IRBuilderBPF::CreateStrncmp(Value *val1, - Value *val2, +Value *IRBuilderBPF::CreateStrncmp(Value *str1, + uint64_t str1_size, + Value *str2, + uint64_t str2_size, uint64_t n, bool inverse) { @@ -755,40 +739,21 @@ Value *IRBuilderBPF::CreateStrncmp(Value *val1, // Check if the compared strings are literals. // If so, we can avoid storing the literal in memory. std::optional literal1; - if (auto constString1 = dyn_cast(val1)) + if (auto constString1 = dyn_cast(str1)) literal1 = constString1->getAsString(); - else if (isa(val1)) + else if (isa(str1)) literal1 = ""; else literal1 = std::nullopt; std::optional literal2; - if (auto constString2 = dyn_cast(val2)) + if (auto constString2 = dyn_cast(str2)) literal2 = constString2->getAsString(); - else if (isa(val2)) + else if (isa(str2)) literal2 = ""; else literal2 = std::nullopt; - auto *val1p = dyn_cast(val1->getType()); - auto *val2p = dyn_cast(val2->getType()); -#ifndef NDEBUG - if (!literal1) - { - assert(val1p); - assert(val1p->getPointerElementType()->isArrayTy() && - val1p->getPointerElementType()->getArrayElementType() == - getInt8Ty()); - } - if (!literal2) - { - assert(val2p); - assert(val2p->getPointerElementType()->isArrayTy() && - val2p->getPointerElementType()->getArrayElementType() == - getInt8Ty()); - } -#endif - Function *parent = GetInsertBlock()->getParent(); AllocaInst *store = CreateAllocaBPF(getInt1Ty(), "strcmp.result"); BasicBlock *str_ne = BasicBlock::Create(module_.getContext(), @@ -815,8 +780,8 @@ Value *IRBuilderBPF::CreateStrncmp(Value *val1, l = getInt8(literal1->c_str()[i]); else { - auto *ptr_l = CreateGEP(val1p->getPointerElementType(), - val1, + auto *ptr_l = CreateGEP(ArrayType::get(getInt8Ty(), str1_size), + str1, { getInt32(0), getInt32(i) }); l = CreateLoad(getInt8Ty(), ptr_l); } @@ -826,8 +791,8 @@ Value *IRBuilderBPF::CreateStrncmp(Value *val1, r = getInt8(literal2->c_str()[i]); else { - auto *ptr_r = CreateGEP(val2p->getPointerElementType(), - val2, + auto *ptr_r = CreateGEP(ArrayType::get(getInt8Ty(), str2_size), + str2, { getInt32(0), getInt32(i) }); r = CreateLoad(getInt8Ty(), ptr_r); } @@ -987,11 +952,9 @@ void IRBuilderBPF::CreateGetCurrentComm(Value *ctx, size_t size, const location &loc) { - assert(buf->getType()->getPointerElementType()->isArrayTy() && - buf->getType()->getPointerElementType()->getArrayNumElements() >= - size && - buf->getType()->getPointerElementType()->getArrayElementType() == - getInt8Ty()); + assert(buf->getAllocatedType()->isArrayTy() && + buf->getAllocatedType()->getArrayNumElements() >= size && + buf->getAllocatedType()->getArrayElementType() == getInt8Ty()); // long bpf_get_current_comm(char *buf, int size_of_buf) // Return: 0 on success or negative error @@ -1070,7 +1033,7 @@ void IRBuilderBPF::CreateSignal(Value *ctx, Value *sig, const location &loc) Instruction::IntToPtr, getInt64(libbpf::BPF_FUNC_send_signal), signal_func_ptr_type); - CallInst *call = createCall(signal_func, { sig }, "signal"); + CallInst *call = createCall(signal_func_type, signal_func, { sig }, "signal"); CreateHelperErrorCond(ctx, call, libbpf::BPF_FUNC_send_signal, loc); } @@ -1084,7 +1047,7 @@ void IRBuilderBPF::CreateOverrideReturn(Value *ctx, Value *rc) Constant *override_func = ConstantExpr::getCast(Instruction::IntToPtr, getInt64(libbpf::BPF_FUNC_override_return), override_func_ptr_type); - createCall(override_func, { ctx, rc }, "override"); + createCall(override_func_type, override_func, { ctx, rc }, "override"); } CallInst *IRBuilderBPF::CreateSkbOutput(Value *skb, @@ -1119,7 +1082,8 @@ CallInst *IRBuilderBPF::CreateSkbOutput(Value *skb, Instruction::IntToPtr, getInt64(libbpf::BPF_FUNC_skb_output), skb_output_func_ptr_type); - CallInst *call = createCall(skb_output_func, + CallInst *call = createCall(skb_output_func_type, + skb_output_func, { skb, map_ptr, flags, data, size_val }, "skb_output"); return call; @@ -1328,7 +1292,8 @@ void IRBuilderBPF::CreateSeqPrintf(Value *ctx, CreateGEP(getInt64Ty(), meta, getInt64(0)), "seq"); - CallInst *call = createCall(seq_printf_func, + CallInst *call = createCall(seq_printf_func_type, + seq_printf_func, { seq, fmt, fmt_size, data, data_len }, "seq_printf"); CreateHelperErrorCond(ctx, call, libbpf::BPF_FUNC_seq_printf, loc); diff --git a/src/ast/irbuilderbpf.h b/src/ast/irbuilderbpf.h index b6a06778..19b28180 100644 --- a/src/ast/irbuilderbpf.h +++ b/src/ast/irbuilderbpf.h @@ -106,17 +106,11 @@ public: bool isVolatile = false, std::optional addrSpace = std::nullopt); CallInst *CreateProbeReadStr(Value *ctx, - AllocaInst *dst, + Value *dst, llvm::Value *size, Value *src, AddrSpace as, const location &loc); - CallInst *CreateProbeReadStr(Value *ctx, - AllocaInst *dst, - size_t size, - Value *src, - AddrSpace as, - const location &loc); CallInst *CreateProbeReadStr(Value *ctx, Value *dst, size_t size, @@ -131,7 +125,12 @@ public: pid_t pid, AddrSpace as, const location &loc); - Value *CreateStrncmp(Value *val1, Value *val2, uint64_t n, bool inverse); + Value *CreateStrncmp(Value *str1, + uint64_t str1_size, + Value *str2, + uint64_t str2_size, + uint64_t n, + bool inverse); CallInst *CreateGetNs(bool boot_time, const location &loc); CallInst *CreateGetPidTgid(const location &loc); CallInst *CreateGetCurrentCgroupId(const location &loc); @@ -147,7 +146,10 @@ public: ArrayRef args, const Twine &Name, const location *loc = nullptr); - CallInst *createCall(Value *callee, ArrayRef args, const Twine &Name); + CallInst *createCall(FunctionType *callee_type, + Value *callee, + ArrayRef args, + const Twine &Name); void CreateGetCurrentComm(Value *ctx, AllocaInst *buf, size_t size, const location& loc); void CreatePerfEventOutput(Value *ctx, Value *data, @@ -205,9 +207,6 @@ private: AddrSpace as, const location &loc); CallInst *createMapLookup(int mapid, Value *key); - Constant *createProbeReadStrFn(llvm::Type *dst, - llvm::Type *src, - AddrSpace as); libbpf::bpf_func_id selectProbeReadHelper(AddrSpace as, bool str); llvm::Type *getKernelPointerStorageTy(); diff --git a/src/ast/passes/codegen_llvm.cpp b/src/ast/passes/codegen_llvm.cpp index d4a5e1c7..0703d196 100644 --- a/src/ast/passes/codegen_llvm.cpp +++ b/src/ast/passes/codegen_llvm.cpp @@ -1152,8 +1152,12 @@ void CodegenLLVM::visit(Call &call) auto left_string = getString(left_arg); auto right_string = getString(right_arg); - expr_ = b_.CreateStrncmp( - left_string.first, right_string.first, size, false); + expr_ = b_.CreateStrncmp(left_string.first, + left_string.second, + right_string.first, + right_string.second, + size, + false); } else if (call.func == "override") { @@ -1284,8 +1288,7 @@ void CodegenLLVM::visit(Variable &var) else { auto *var_alloca = variables_[var.ident]; - expr_ = b_.CreateLoad(var_alloca->getType()->getPointerElementType(), - var_alloca); + expr_ = b_.CreateLoad(var_alloca->getAllocatedType(), var_alloca); } } @@ -1325,7 +1328,12 @@ void CodegenLLVM::binop_string(Binop &binop) auto right_string = getString(binop.right); size_t len = std::min(left_string.second, right_string.second); - expr_ = b_.CreateStrncmp(left_string.first, right_string.first, len, inverse); + expr_ = b_.CreateStrncmp(left_string.first, + left_string.second, + right_string.first, + right_string.second, + len, + inverse); } void CodegenLLVM::binop_buf(Binop &binop) @@ -1349,7 +1357,12 @@ void CodegenLLVM::binop_buf(Binop &binop) size_t len = std::min(binop.left->type.GetSize(), binop.right->type.GetSize()); - expr_ = b_.CreateStrncmp(left_string, right_string, len, inverse); + expr_ = b_.CreateStrncmp(left_string, + binop.left->type.GetSize(), + right_string, + binop.right->type.GetSize(), + len, + inverse); } void CodegenLLVM::binop_int(Binop &binop) @@ -3498,9 +3511,8 @@ void CodegenLLVM::createIncDec(Unop &unop) else if (unop.expr->is_variable) { Variable &var = static_cast(*unop.expr); - Value *oldval = b_.CreateLoad( - variables_[var.ident]->getType()->getPointerElementType(), - variables_[var.ident]); + Value *oldval = b_.CreateLoad(variables_[var.ident]->getAllocatedType(), + variables_[var.ident]); Value *newval; if (is_increment) newval = b_.CreateAdd(oldval, b_.GetIntSameSize(step, oldval));