While exploring dependency analysis capabilities, I've discovered by current design MemDepPrinter has a print() function, which is never called anywhere. Thus, opt -print-memdeps never prints anything. This trivial patch change the pass to print the dependencies right from the function pass.
Details
Details
- Reviewers
- None
Diff Detail
Diff Detail
Event Timeline
Comment Actions
Example:
$ cat example.c void vector_sum(int length, float* in1, float* in2, float* out) { for (int i = 0; i < length; i++) out[i] = in1[i] + in2[i]; } #include <malloc.h> #include <stdio.h> #include <stdlib.h> int main(int argc, char* argv[]) { if (argc != 2) return 1; int length = atoi(argv[1]); float* in1 = (float*)malloc(length * sizeof(float)); float* in2 = (float*)malloc(length * sizeof(float)); float* out = (float*)malloc(length * sizeof(float)); for (int i = 0; i < length; i++) { in1[i] = drand48(); in2[i] = drand48(); } vector_sum(length, in1, in2, out); //printf("%f\n", out[length - 1]); return 0; } $ clang -emit-llvm -c -S -O1 example.c -o - | opt -memdep -print-memdeps -o /dev/null Function vector_sum memory dependencies: Unknown in block %for.body Unknown in block %entry %0 = load float* %arrayidx, align 4, !tbaa !1 Unknown in block %for.body Unknown in block %entry %1 = load float* %arrayidx2, align 4, !tbaa !1 Def from: %1 = load float* %arrayidx2, align 4, !tbaa !1 store float %add, float* %arrayidx4, align 4, !tbaa !1 Function main memory dependencies: Unknown in block %entry %0 = load i8** %arrayidx, align 8, !tbaa !1 Clobber from: %0 = load i8** %arrayidx, align 8, !tbaa !1 %call = tail call i32 @atoi(i8* %0) #3 Clobber from: %call = tail call i32 @atoi(i8* %0) #3 %call1 = tail call noalias i8* @malloc(i64 %mul) #4 Clobber from: %call1 = tail call noalias i8* @malloc(i64 %mul) #4 %call4 = tail call noalias i8* @malloc(i64 %mul) #4 Clobber from: %call4 = tail call noalias i8* @malloc(i64 %mul) #4 %call7 = tail call noalias i8* @malloc(i64 %mul) #4 Clobber in block %if.end from: %call7 = tail call noalias i8* @malloc(i64 %mul) #4 Clobber in block %for.body from: store float %conv14, float* %arrayidx16, align 4, !tbaa !5 %call10 = tail call double @drand48() #4 Clobber from: %call10 = tail call double @drand48() #4 store float %conv11, float* %arrayidx12, align 4, !tbaa !5 Clobber from: store float %conv11, float* %arrayidx12, align 4, !tbaa !5 %call13 = tail call double @drand48() #4 Clobber from: %call13 = tail call double @drand48() #4 store float %conv14, float* %arrayidx16, align 4, !tbaa !5 Clobber in block %if.end from: %call7 = tail call noalias i8* @malloc(i64 %mul) #4 Clobber in block %for.body from: store float %conv14, float* %arrayidx16, align 4, !tbaa !5 tail call void @vector_sum(i32 %call, float* %1, float* %2, float* %3) Function atoi memory dependencies: NonFuncLocal %call = tail call i64 @strtol(i8* nocapture %__nptr, i8** null, i32 10) #3
Comment Actions
The print-memdeps pass was written to be used with opt's -analyze feature. If you run opt -print-memdeps -analyze, it prints.
Comment Actions
Hi Dan,
OK, I missed that because other -print-* passes are just printing to stderr without -analyze... So is -analyze necessary?
Also, I have a question: why for the store from 2 loads in the IR code below I get store having only single Def dependency on one of the loads, not on both of them?
Thanks,
- D.
define void @vector_sum(i32 %length, float* nocapture readonly %in1, float* nocapture readonly %in2, float* nocapture %out) #0 { entry: %cmp9 = icmp sgt i32 %length, 0 br i1 %cmp9, label %for.body, label %for.end for.body: ; preds = %entry, %for.body %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ] %arrayidx = getelementptr inbounds float* %in1, i64 %indvars.iv %0 = load float* %arrayidx, align 4, !tbaa !1 %arrayidx2 = getelementptr inbounds float* %in2, i64 %indvars.iv %1 = load float* %arrayidx2, align 4, !tbaa !1 %add = fadd float %0, %1 %arrayidx4 = getelementptr inbounds float* %out, i64 %indvars.iv store float %add, float* %arrayidx4, align 4, !tbaa !1 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 %exitcond = icmp eq i32 %lftr.wideiv, %length br i1 %exitcond, label %for.end, label %for.body for.end: ; preds = %for.body, %entry ret void } $ clang -emit-llvm example.c -O1 -S -o - | opt -memdep -print-memdeps -o /dev/null Function vector_sum memory dependencies: Unknown in block %for.body Unknown in block %entry %0 = load float* %arrayidx, align 4, !tbaa !1 Unknown in block %for.body Unknown in block %entry %1 = load float* %arrayidx2, align 4, !tbaa !1 Def from: %1 = load float* %arrayidx2, align 4, !tbaa !1 store float %add, float* %arrayidx4, align 4, !tbaa !1
Comment Actions
I am not presently using the memdep printer pass, so if it's not working properly, it's fine with me to remove it from the tree.