hfinkel added inline comments. ================ Comment at: lib/CodeGen/CGExpr.cpp:1286 @@ -1283,1 +1285,3 @@ + Value = Builder.CreateNoAlias(Value, NAI->second); + if (Ty->isAtomicType() || ---------------- rjmccall wrote: > hfinkel wrote: > > rjmccall wrote: > > > This is very strange. Why do the aliasing properties of an address cause > > > metadata to be attached to the value stored into it? Shouldn't the > > > metadata be on the address (in which case, perhaps it should have been > > > attached to the load from the restrict pointer?) or the store? > > > > > > Also, please find some way to avoid doing a DenseMap lookup on every > > > single store. I would guess that the address only has an entry in that > > > table if it was restrict-qualified; you can probably find a way to pass > > > that information down. > > > This is very strange. Why do the aliasing properties of an address cause > > > metadata to be attached to the value stored into it? Shouldn't the > > > metadata be on the address (in which case, perhaps it should have been > > > attached to the load from the restrict pointer?) or the store? > > > > > > To be clear, this is not the metadata, this is the intrinsic; the metadata > > needs to be attached to all access in the scope. The intrinsic wraps the > > 'noalias' address. And this is "wrapping" the restrict-qualified address > > with the llvm.noalias intrinsic before it is stored into the stack space > > allocated for the local variable. > > > > > Also, please find some way to avoid doing a DenseMap lookup on every > > > single store. I would guess that the address only has an entry in that > > > table if it was restrict-qualified; you can probably find a way to pass > > > that information down. > > > > You are right: some (indirect) caller of this function should see a > > restrict-qualified variable. Maybe this information should end up in the > > LValue structure? > > > > Maybe it is worth now thinking about that should be the follow-on patch, > > because that also might influence the design. This patch handles direct > > restrict-qualified local variables, but does not handle the case where the > > variables are inside a structure. Specifically, I mean this: > > > > struct V { > > double * restrict x; > > double * restrict y; > > double * restrict z; > > }; > > > > void foo() { > > V v = { getX(), getY(), getZ() }; > > // The stores that compose this initializer need to be wrapped in > > @llvm.noalias also. > > } > > > > So I'd like to end up with a design for this patch that is easy to extend > > to handle the restrict-qualified-local-structure-member case as well. > "Value" is the value being stored to the address. > > If I've got code like this: > double * restrict addr = get_addr(); > double value = get_value(); > *addr = value; > > you are producing IR like > %addr = call double* @get_addr() > %value = call double get_value() > %value2 = call @llvm.noalias(double %value) > store %value2, %addr > > This is what I'm saying does not make any sense, because there's nothing > special about %value; the restrictions are on %addr. I think you probably > just have a bug in your patch and meant to use Addr. > > > You are right: some (indirect) caller of this function should see a > > restrict-qualified variable. Maybe this information should end up in the > > LValue structure? > > Yes, we already store when l-values are volatile, so storing that they're > restrict should be easy. No, this is not correct. If I have code like this:
double * restrict addr = get_addr(); double value = get_value(); *addr = value; then we don't get code like this: %addr = call double* @get_addr() %value = call double get_value() %value2 = call @llvm.noalias(double %value) store %value2, %addr The code that Clang generates does not look like that: it does not generate an SSA variable for %addr, it generates a local stack location for it, and then loads/stores from that location when accessed. The only address that appear in NoAliasAddrMap are the address of the local allocas for the restrict-qualified variables themselves. It is only the pointer values being stored into the local restrict-qualified variables themselves that get wrapped. If you look at the regression test, I think it is clear that the code does the right thing. (If that's not clear, I should improve the test.) ================ Comment at: lib/CodeGen/CGExpr.cpp:1286 @@ -1283,1 +1285,3 @@ + Value = Builder.CreateNoAlias(Value, NAI->second); + if (Ty->isAtomicType() || ---------------- hfinkel wrote: > rjmccall wrote: > > hfinkel wrote: > > > rjmccall wrote: > > > > This is very strange. Why do the aliasing properties of an address > > > > cause metadata to be attached to the value stored into it? Shouldn't > > > > the metadata be on the address (in which case, perhaps it should have > > > > been attached to the load from the restrict pointer?) or the store? > > > > > > > > Also, please find some way to avoid doing a DenseMap lookup on every > > > > single store. I would guess that the address only has an entry in that > > > > table if it was restrict-qualified; you can probably find a way to pass > > > > that information down. > > > > This is very strange. Why do the aliasing properties of an address > > > > cause metadata to be attached to the value stored into it? Shouldn't > > > > the metadata be on the address (in which case, perhaps it should have > > > > been attached to the load from the restrict pointer?) or the store? > > > > > > > > > To be clear, this is not the metadata, this is the intrinsic; the > > > metadata needs to be attached to all access in the scope. The intrinsic > > > wraps the 'noalias' address. And this is "wrapping" the > > > restrict-qualified address with the llvm.noalias intrinsic before it is > > > stored into the stack space allocated for the local variable. > > > > > > > Also, please find some way to avoid doing a DenseMap lookup on every > > > > single store. I would guess that the address only has an entry in that > > > > table if it was restrict-qualified; you can probably find a way to pass > > > > that information down. > > > > > > You are right: some (indirect) caller of this function should see a > > > restrict-qualified variable. Maybe this information should end up in the > > > LValue structure? > > > > > > Maybe it is worth now thinking about that should be the follow-on patch, > > > because that also might influence the design. This patch handles direct > > > restrict-qualified local variables, but does not handle the case where > > > the variables are inside a structure. Specifically, I mean this: > > > > > > struct V { > > > double * restrict x; > > > double * restrict y; > > > double * restrict z; > > > }; > > > > > > void foo() { > > > V v = { getX(), getY(), getZ() }; > > > // The stores that compose this initializer need to be wrapped in > > > @llvm.noalias also. > > > } > > > > > > So I'd like to end up with a design for this patch that is easy to extend > > > to handle the restrict-qualified-local-structure-member case as well. > > "Value" is the value being stored to the address. > > > > If I've got code like this: > > double * restrict addr = get_addr(); > > double value = get_value(); > > *addr = value; > > > > you are producing IR like > > %addr = call double* @get_addr() > > %value = call double get_value() > > %value2 = call @llvm.noalias(double %value) > > store %value2, %addr > > > > This is what I'm saying does not make any sense, because there's nothing > > special about %value; the restrictions are on %addr. I think you probably > > just have a bug in your patch and meant to use Addr. > > > > > You are right: some (indirect) caller of this function should see a > > > restrict-qualified variable. Maybe this information should end up in the > > > LValue structure? > > > > Yes, we already store when l-values are volatile, so storing that they're > > restrict should be easy. > No, this is not correct. If I have code like this: > > double * restrict addr = get_addr(); > double value = get_value(); > *addr = value; > > then we don't get code like this: > > %addr = call double* @get_addr() > %value = call double get_value() > %value2 = call @llvm.noalias(double %value) > store %value2, %addr > > The code that Clang generates does not look like that: it does not generate > an SSA variable for %addr, it generates a local stack location for it, and > then loads/stores from that location when accessed. The only address that > appear in NoAliasAddrMap are the address of the local allocas for the > restrict-qualified variables themselves. It is only the pointer values being > stored into the local restrict-qualified variables themselves that get > wrapped. > > If you look at the regression test, I think it is clear that the code does > the right thing. (If that's not clear, I should improve the test.) > Yes, we already store when l-values are volatile, so storing that they're > restrict should be easy. FWIW, LValue already keeps track of whether or not the value is restrict qualified (along with whether or not it is volatile). I'll see if I can predicate the map lookup on that, which may be the best solution (does not increase the size of LValue for an uncommon case, but also does not perform a map lookup for every store). http://reviews.llvm.org/D9403 _______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits