@@ -712,9 +712,10 @@ void CodegenLLVM::visit(Call &call)
712712 b_.getInt64Ty (),
713713 call.vargs .front ()->type .IsSigned ());
714714 Value *log2 = b_.CreateCall (log2_func_, { expr_, k }, " log2" );
715- AllocaInst * key = getHistMapKey (map, log2);
715+ auto key = getHistMapKey (map, log2, call. loc );
716716 b_.CreateMapElemAdd (ctx_, map, key, b_.getInt64 (1 ), call.loc );
717- b_.CreateLifetimeEnd (key);
717+ if (dyn_cast<AllocaInst>(key))
718+ b_.CreateLifetimeEnd (key);
718719 expr_ = nullptr ;
719720 } else if (call.func == " lhist" ) {
720721 if (!linear_func_)
@@ -750,10 +751,10 @@ void CodegenLLVM::visit(Call &call)
750751 { value, min, max, step },
751752 " linear" );
752753
753- AllocaInst * key = getHistMapKey (map, linear);
754+ auto key = getHistMapKey (map, linear, call. loc );
754755 b_.CreateMapElemAdd (ctx_, map, key, b_.getInt64 (1 ), call.loc );
755-
756- b_.CreateLifetimeEnd (key);
756+ if (dyn_cast<AllocaInst>(key))
757+ b_.CreateLifetimeEnd (key);
757758 expr_ = nullptr ;
758759 } else if (call.func == " delete" ) {
759760 auto &arg0 = *call.vargs .at (0 );
@@ -3018,13 +3019,19 @@ std::tuple<Value *, CodegenLLVM::ScopedExprDeleter> CodegenLLVM::getMapKey(
30183019 Expression *key_expr)
30193020{
30203021 Value *key;
3021- bool alloca_created_here = true ;
3022+ const auto alloca_created_here = needMapKeyAllocation (map, key_expr);
3023+
30223024 if (key_expr) {
30233025 auto scoped_del = accept (key_expr);
3026+ const auto &key_type = map.key_type ;
3027+ // Allocation needs to be done after recursing via accept(key_expr)
3028+ // so expr_ will be set properly
3029+ key = alloca_created_here ? b_.CreateMapKeyAllocation (key_type,
3030+ map.ident + " _key" ,
3031+ key_expr->loc )
3032+ : expr_;
30243033 if (inBpfMemory (key_expr->type )) {
3025- auto &key_type = map.key_type ;
30263034 if (!key_expr->type .IsSameSizeRecursive (key_type)) {
3027- key = b_.CreateAllocaBPF (key_type, map.ident + " _key" );
30283035 b_.CreateMemsetBPF (key, b_.getInt8 (0 ), key_type.GetSize ());
30293036 if (key_expr->type .IsTupleTy ()) {
30303037 createTupleCopy (key_expr->type , key_type, key, expr_);
@@ -3036,25 +3043,23 @@ std::tuple<Value *, CodegenLLVM::ScopedExprDeleter> CodegenLLVM::getMapKey(
30363043 << " Expression Type Size: " << key_expr->type .GetSize ();
30373044 }
30383045 } else {
3039- key = expr_;
30403046 // Call-ee freed
30413047 scoped_del.disarm ();
3042-
3043- // We don't have enough visibility into where key comes from to safely
3044- // end its lifetime. It could be a variable, for example.
3045- alloca_created_here = false ;
30463048 }
30473049 } else if (map.key_type .IsIntTy ()) {
3048- key = b_.CreateAllocaBPF (map.key_type , map.ident + " _key" );
30493050 // Integers are always stored as 64-bit in map keys
30503051 b_.CreateStore (
30513052 b_.CreateIntCast (expr_, b_.getInt64Ty (), key_expr->type .IsSigned ()),
30523053 key);
30533054 } else {
3054- key = b_.CreateAllocaBPF (key_expr->type , map.ident + " _key" );
30553055 if (key_expr->type .IsArrayTy () || key_expr->type .IsRecordTy ()) {
30563056 // We need to read the entire array/struct and save it
3057- b_.CreateProbeRead (ctx_, key, key_expr->type , expr_, key_expr->loc );
3057+ b_.CreateProbeRead (ctx_,
3058+ b_.CreatePointerCast (
3059+ key, b_.GetType (key_expr->type )->getPointerTo ()),
3060+ key_expr->type ,
3061+ expr_,
3062+ key_expr->loc );
30583063 } else {
30593064 b_.CreateStore (
30603065 b_.CreateIntCast (expr_, b_.getInt64Ty (), key_expr->type .IsSigned ()),
@@ -3063,19 +3068,23 @@ std::tuple<Value *, CodegenLLVM::ScopedExprDeleter> CodegenLLVM::getMapKey(
30633068 }
30643069 } else {
30653070 // No map key (e.g., @ = 1;). Use 0 as a key.
3066- key = b_.CreateAllocaBPF (CreateUInt64 (), map.ident + " _key" );
3071+ assert (alloca_created_here);
3072+ key = b_.CreateMapKeyAllocation (CreateUInt64 (),
3073+ map.ident + " _key" ,
3074+ map.loc );
30673075 b_.CreateStore (b_.getInt64 (0 ), key);
30683076 }
30693077
30703078 auto key_deleter = [this , key, alloca_created_here]() {
3071- if (alloca_created_here)
3079+ if (alloca_created_here && dyn_cast<AllocaInst>(key) )
30723080 b_.CreateLifetimeEnd (key);
30733081 };
30743082 return std::make_tuple (key, ScopedExprDeleter (std::move (key_deleter)));
30753083}
30763084
3077- AllocaInst *CodegenLLVM::getMultiMapKey (Map &map,
3078- const std::vector<Value *> &extra_keys)
3085+ Value *CodegenLLVM::getMultiMapKey (Map &map,
3086+ const std::vector<Value *> &extra_keys,
3087+ const location &loc)
30793088{
30803089 size_t size = map.key_type .GetSize ();
30813090 for (auto *extra_key : extra_keys) {
@@ -3084,7 +3093,9 @@ AllocaInst *CodegenLLVM::getMultiMapKey(Map &map,
30843093
30853094 // If key ever changes to not be allocated here, be sure to update getMapKey()
30863095 // as well to take the new lifetime semantics into account.
3087- AllocaInst *key = b_.CreateAllocaBPF (size, map.ident + " _key" );
3096+ auto key = b_.CreateMapKeyAllocation (CreateArray (size, CreateInt8 ()),
3097+ map.ident + " _key" ,
3098+ loc);
30883099 auto *key_type = ArrayType::get (b_.getInt8Ty (), size);
30893100
30903101 int offset = 0 ;
@@ -3153,12 +3164,12 @@ AllocaInst *CodegenLLVM::getMultiMapKey(Map &map,
31533164 return key;
31543165}
31553166
3156- AllocaInst *CodegenLLVM::getHistMapKey (Map &map, Value *log2)
3167+ Value *CodegenLLVM::getHistMapKey (Map &map, Value *log2, const location &loc )
31573168{
31583169 if (map.key_expr )
3159- return getMultiMapKey (map, { log2 });
3170+ return getMultiMapKey (map, { log2 }, loc );
31603171
3161- AllocaInst * key = b_.CreateAllocaBPF (CreateUInt64 (), map.ident + " _key" );
3172+ auto key = b_.CreateMapKeyAllocation (CreateUInt64 (), map.ident + " _key" , loc );
31623173 b_.CreateStore (log2, key);
31633174 return key;
31643175}
0 commit comments