yonghong-song created this revision. yonghong-song added reviewers: anakryiko, ast. Herald added subscribers: llvm-commits, cfe-commits, hiraditya. Herald added projects: clang, LLVM.
[The patch needs more work e.g. to create proper test, to be agreed on interface, etc.] This patch added support of expression with typedef type for FIELD_EXISTENCE relocation. This tries to address the following use case: enum { FIELD_EXISTENCE = 2, }; typedef unsigned long u64; typedef unsigned int u32; struct bpf_perf_event_data_kern; typedef u64 (*btf_bpf_read_branch_records)(struct bpf_perf_event_data_kern *, void *, u32, u64); int test() { btf_bpf_read_branch_records a; return __builtin_preserve_field_info(a, FIELD_EXISTENCE); } A relocation with a type of typedef 'btf_bpf_read_branch_records' will be recorded. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D83242 Files: clang/lib/CodeGen/CGBuiltin.cpp clang/lib/Sema/SemaChecking.cpp llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp Index: llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp =================================================================== --- llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp +++ llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp @@ -277,7 +277,7 @@ } if (GV->getName().startswith("llvm.bpf.preserve.field.info")) { CInfo.Kind = BPFPreserveFieldInfoAI; - CInfo.Metadata = nullptr; + CInfo.Metadata = Call->getMetadata(LLVMContext::MD_preserve_access_index); // Check validity of info_kind as clang did not check this. uint64_t InfoKind = getConstant(Call->getArgOperand(1)); if (InfoKind >= BPFCoreSharedInfo::MAX_FIELD_RELOC_KIND) @@ -742,6 +742,13 @@ break; } + if (CInfo.Kind == BPFPreserveFieldInfoAI) { + // typedef type. + TypeName = std::string(PossibleTypeDef->getName()); + TypeMeta = PossibleTypeDef; + break; + } + assert(CInfo.Kind == BPFPreserveArrayAI); // Array entries will always be consumed for accumulative initial index. Index: clang/lib/Sema/SemaChecking.cpp =================================================================== --- clang/lib/Sema/SemaChecking.cpp +++ clang/lib/Sema/SemaChecking.cpp @@ -2582,6 +2582,15 @@ return false; } + // The second argument needs to be a constant int + Arg = TheCall->getArg(1); + llvm::APSInt Value; + if (!Arg->isIntegerConstantExpr(Value, Context)) { + Diag(Arg->getBeginLoc(), diag::err_preserve_field_info_not_const) + << 2 << Arg->getSourceRange(); + return true; + } + // The first argument needs to be a record field access. // If it is an array element access, we delay decision // to BPF backend to check whether the access is a @@ -2590,21 +2599,14 @@ if (Arg->getType()->getAsPlaceholderType() || (Arg->IgnoreParens()->getObjectKind() != OK_BitField && !dyn_cast<MemberExpr>(Arg->IgnoreParens()) && - !dyn_cast<ArraySubscriptExpr>(Arg->IgnoreParens()))) { + !dyn_cast<ArraySubscriptExpr>(Arg->IgnoreParens()) && + // Value 2 here represents reloc kind FIELD_EXISTENCE. + (Value != 2 || !Arg->getType()->getAs<TypedefType>()))) { Diag(Arg->getBeginLoc(), diag::err_preserve_field_info_not_field) << 1 << Arg->getSourceRange(); return true; } - // The second argument needs to be a constant int - Arg = TheCall->getArg(1); - llvm::APSInt Value; - if (!Arg->isIntegerConstantExpr(Value, Context)) { - Diag(Arg->getBeginLoc(), diag::err_preserve_field_info_not_const) - << 2 << Arg->getSourceRange(); - return true; - } - TheCall->setType(Context.UnsignedIntTy); return false; } Index: clang/lib/CodeGen/CGBuiltin.cpp =================================================================== --- clang/lib/CodeGen/CGBuiltin.cpp +++ clang/lib/CodeGen/CGBuiltin.cpp @@ -10966,11 +10966,17 @@ ConstantInt *C = cast<ConstantInt>(EmitScalarExpr(E->getArg(1))); Value *InfoKind = ConstantInt::get(Int64Ty, C->getSExtValue()); + llvm::DIType *DbgInfo = + getDebugInfo()->getOrCreateStandaloneType(E->getArg(0)->getType(), + E->getArg(0)->getExprLoc()); + // Built the IR for the preserve_field_info intrinsic. llvm::Function *FnGetFieldInfo = llvm::Intrinsic::getDeclaration( &CGM.getModule(), llvm::Intrinsic::bpf_preserve_field_info, {FieldAddr->getType()}); - return Builder.CreateCall(FnGetFieldInfo, {FieldAddr, InfoKind}); + CallInst *Fn = Builder.CreateCall(FnGetFieldInfo, {FieldAddr, InfoKind}); + Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo); + return Fn; } case BPF::BI__builtin_btf_type_id: { Value *FieldVal = nullptr;
Index: llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp =================================================================== --- llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp +++ llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp @@ -277,7 +277,7 @@ } if (GV->getName().startswith("llvm.bpf.preserve.field.info")) { CInfo.Kind = BPFPreserveFieldInfoAI; - CInfo.Metadata = nullptr; + CInfo.Metadata = Call->getMetadata(LLVMContext::MD_preserve_access_index); // Check validity of info_kind as clang did not check this. uint64_t InfoKind = getConstant(Call->getArgOperand(1)); if (InfoKind >= BPFCoreSharedInfo::MAX_FIELD_RELOC_KIND) @@ -742,6 +742,13 @@ break; } + if (CInfo.Kind == BPFPreserveFieldInfoAI) { + // typedef type. + TypeName = std::string(PossibleTypeDef->getName()); + TypeMeta = PossibleTypeDef; + break; + } + assert(CInfo.Kind == BPFPreserveArrayAI); // Array entries will always be consumed for accumulative initial index. Index: clang/lib/Sema/SemaChecking.cpp =================================================================== --- clang/lib/Sema/SemaChecking.cpp +++ clang/lib/Sema/SemaChecking.cpp @@ -2582,6 +2582,15 @@ return false; } + // The second argument needs to be a constant int + Arg = TheCall->getArg(1); + llvm::APSInt Value; + if (!Arg->isIntegerConstantExpr(Value, Context)) { + Diag(Arg->getBeginLoc(), diag::err_preserve_field_info_not_const) + << 2 << Arg->getSourceRange(); + return true; + } + // The first argument needs to be a record field access. // If it is an array element access, we delay decision // to BPF backend to check whether the access is a @@ -2590,21 +2599,14 @@ if (Arg->getType()->getAsPlaceholderType() || (Arg->IgnoreParens()->getObjectKind() != OK_BitField && !dyn_cast<MemberExpr>(Arg->IgnoreParens()) && - !dyn_cast<ArraySubscriptExpr>(Arg->IgnoreParens()))) { + !dyn_cast<ArraySubscriptExpr>(Arg->IgnoreParens()) && + // Value 2 here represents reloc kind FIELD_EXISTENCE. + (Value != 2 || !Arg->getType()->getAs<TypedefType>()))) { Diag(Arg->getBeginLoc(), diag::err_preserve_field_info_not_field) << 1 << Arg->getSourceRange(); return true; } - // The second argument needs to be a constant int - Arg = TheCall->getArg(1); - llvm::APSInt Value; - if (!Arg->isIntegerConstantExpr(Value, Context)) { - Diag(Arg->getBeginLoc(), diag::err_preserve_field_info_not_const) - << 2 << Arg->getSourceRange(); - return true; - } - TheCall->setType(Context.UnsignedIntTy); return false; } Index: clang/lib/CodeGen/CGBuiltin.cpp =================================================================== --- clang/lib/CodeGen/CGBuiltin.cpp +++ clang/lib/CodeGen/CGBuiltin.cpp @@ -10966,11 +10966,17 @@ ConstantInt *C = cast<ConstantInt>(EmitScalarExpr(E->getArg(1))); Value *InfoKind = ConstantInt::get(Int64Ty, C->getSExtValue()); + llvm::DIType *DbgInfo = + getDebugInfo()->getOrCreateStandaloneType(E->getArg(0)->getType(), + E->getArg(0)->getExprLoc()); + // Built the IR for the preserve_field_info intrinsic. llvm::Function *FnGetFieldInfo = llvm::Intrinsic::getDeclaration( &CGM.getModule(), llvm::Intrinsic::bpf_preserve_field_info, {FieldAddr->getType()}); - return Builder.CreateCall(FnGetFieldInfo, {FieldAddr, InfoKind}); + CallInst *Fn = Builder.CreateCall(FnGetFieldInfo, {FieldAddr, InfoKind}); + Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo); + return Fn; } case BPF::BI__builtin_btf_type_id: { Value *FieldVal = nullptr;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits