Sato, Kento via llvm-dev
2018-Sep-22 00:56 UTC
[llvm-dev] DependenceAnalysisWrapperPass is confused with Simple Flow Dependence
Hi, I’m trying to do dependency analysis using LLVM DependenceAnalysisWrapperPass (Clang/LLVM6.0.0). But, I’m confused by the results. For example, I tried this simple C program (simple.c). int main(int argc, char** argv) { volatile int x = 1, y = 2; y = x; return 0; } If I output the IR, I get this. define i32 @main(i32, i8** nocapture readnone) local_unnamed_addr #0 !dbg !7 { %3 = alloca i32, align 4 %4 = alloca i32, align 4 call void @llvm.dbg.value(metadata i32 %0, metadata !15, metadata !DIExpression()), !dbg !20 call void @llvm.dbg.value(metadata i8** %1, metadata !16, metadata !DIExpression()), !dbg !21 %5 = bitcast i32* %3 to i8*, !dbg !22 call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %5), !dbg !22 call void @llvm.dbg.value(metadata i32 1, metadata !17, metadata !DIExpression()), !dbg !23 store volatile i32 1, i32* %3, align 4, !dbg !23 %6 = bitcast i32* %4 to i8*, !dbg !22 call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %6), !dbg !22 call void @llvm.dbg.value(metadata i32 2, metadata !19, metadata !DIExpression()), !dbg !24 store volatile i32 2, i32* %4, align 4, !dbg !24 %7 = load volatile i32, i32* %3, align 4, !dbg !25 call void @llvm.dbg.value(metadata i32 %7, metadata !17, metadata !DIExpression()), !dbg !23 call void @llvm.dbg.value(metadata i32 %7, metadata !19, metadata !DIExpression()), !dbg !24 store volatile i32 %7, i32* %4, align 4, !dbg !26 call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %6), !dbg !27 call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %5), !dbg !27 ret i32 0, !dbg !28 } Since there is obvious flow dependence in y = x, that is, READ(%7 = load volatile i32, i32* %3, align 4, !dbg !25) and WRITE(store volatile i32 %7, i32* %4, align 4, !dbg !26), I expect that the LLVM DependenceAnalysisWrapperPass can easily detect this flow dependence. So I wrote simple dependence analysis pass (libmyirpass.so) to confirm it. bool runOnFunction(Function &F) { DependenceInfo *depinfo; depinfo = &getAnalysis<DependenceAnalysisWrapperPass>().getDI(); for (inst_iterator Iit = inst_begin(F), Iit_end = inst_end(F); Iit != Iit_end; Iit++) { Instruction &Dst = *Iit; for (inst_iterator Jit = inst_begin(F), Jit_end = inst_end(F); Jit != Jit_end; Jit++) { unique_ptr<Dependence> infoPtr; Instruction &Src = *Jit; Dependence *dep; infoPtr = depinfo->depends(&Src, &Dst, false); /* depends(&Src, &Dest, true); */ dep = infoPtr.get(); if (dep != NULL) { if (dep->isConfused()) errs() << "[C] "; dep->getDst()->print(errs(), false); errs() << " ---> "; dep->getSrc()->print(errs(), false); errs() << "\n"; } } } return false; } However, DependenceAnalysisWrapperPass is confused with this simple flow dependence, i.e., dep->isConfused() returns true, so it outputs this message if I compile simple.c with libmyirpass.so by clang-6.0.0. $ clang++ -g -O0 -std=c++11 -Xclang -load -Xclang ./libmyirpass.so simple.c ... [C] store volatile i32 %7, i32* %4, align 4, !dbg !26 ---> %7 = load volatile i32, i32* %3, align 4, !dbg !25 … I see the same issue with use of both "PassManagerBuilder::EP_EarlyAsPossible" and "PassManagerBuilder::EP_OptimizerLast". I’m wondering why DependenceAnalysisWrapperPass is confused with this simple flow dependence. If I’m misunderstanding about this dependence analysis, please correct me. Thanks, Kento
Bekket McClane via llvm-dev
2018-Sep-22 01:04 UTC
[llvm-dev] DependenceAnalysisWrapperPass is confused with Simple Flow Dependence
Hi, You can dump the debug trace by adding -debug option or -debug-only=“da” to opt Normally Pass authors would print details in debug trace. Or, you can just trace it with gdb, it works well for me all the time. Bests, Bekket> On Sep 21, 2018, at 5:56 PM, Sato, Kento via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > Hi, > > I’m trying to do dependency analysis using LLVM DependenceAnalysisWrapperPass (Clang/LLVM6.0.0). > But, I’m confused by the results. > > For example, I tried this simple C program (simple.c). > > int main(int argc, char** argv) > { > volatile int x = 1, y = 2; > y = x; > return 0; > } > > If I output the IR, I get this. > > define i32 @main(i32, i8** nocapture readnone) local_unnamed_addr #0 !dbg !7 { > %3 = alloca i32, align 4 > %4 = alloca i32, align 4 > call void @llvm.dbg.value(metadata i32 %0, metadata !15, metadata !DIExpression()), !dbg !20 > call void @llvm.dbg.value(metadata i8** %1, metadata !16, metadata !DIExpression()), !dbg !21 > %5 = bitcast i32* %3 to i8*, !dbg !22 > call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %5), !dbg !22 > call void @llvm.dbg.value(metadata i32 1, metadata !17, metadata !DIExpression()), !dbg !23 > store volatile i32 1, i32* %3, align 4, !dbg !23 > %6 = bitcast i32* %4 to i8*, !dbg !22 > call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %6), !dbg !22 > call void @llvm.dbg.value(metadata i32 2, metadata !19, metadata !DIExpression()), !dbg !24 > store volatile i32 2, i32* %4, align 4, !dbg !24 > %7 = load volatile i32, i32* %3, align 4, !dbg !25 > call void @llvm.dbg.value(metadata i32 %7, metadata !17, metadata !DIExpression()), !dbg !23 > call void @llvm.dbg.value(metadata i32 %7, metadata !19, metadata !DIExpression()), !dbg !24 > store volatile i32 %7, i32* %4, align 4, !dbg !26 > call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %6), !dbg !27 > call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %5), !dbg !27 > ret i32 0, !dbg !28 > } > > Since there is obvious flow dependence in y = x, that is, READ(%7 = load volatile i32, i32* %3, align 4, !dbg !25) and WRITE(store volatile i32 %7, i32* %4, align 4, !dbg !26), > I expect that the LLVM DependenceAnalysisWrapperPass can easily detect this flow dependence. > > So I wrote simple dependence analysis pass (libmyirpass.so) to confirm it. > > bool runOnFunction(Function &F) > { > DependenceInfo *depinfo; > depinfo = &getAnalysis<DependenceAnalysisWrapperPass>().getDI(); > for (inst_iterator Iit = inst_begin(F), Iit_end = inst_end(F); Iit != Iit_end; Iit++) { > Instruction &Dst = *Iit; > for (inst_iterator Jit = inst_begin(F), Jit_end = inst_end(F); Jit != Jit_end; Jit++) { > unique_ptr<Dependence> infoPtr; > Instruction &Src = *Jit; > Dependence *dep; > infoPtr = depinfo->depends(&Src, &Dst, false); /* depends(&Src, &Dest, true); */ > dep = infoPtr.get(); > if (dep != NULL) { > if (dep->isConfused()) errs() << "[C] "; > dep->getDst()->print(errs(), false); > errs() << " ---> "; > dep->getSrc()->print(errs(), false); > errs() << "\n"; > } > } > } > return false; > } > > However, DependenceAnalysisWrapperPass is confused with this simple flow dependence, i.e., dep->isConfused() returns true, > so it outputs this message if I compile simple.c with libmyirpass.so by clang-6.0.0. > > $ clang++ -g -O0 -std=c++11 -Xclang -load -Xclang ./libmyirpass.so simple.c > ... > [C] store volatile i32 %7, i32* %4, align 4, !dbg !26 ---> %7 = load volatile i32, i32* %3, align 4, !dbg !25 > … > > I see the same issue with use of both "PassManagerBuilder::EP_EarlyAsPossible" and "PassManagerBuilder::EP_OptimizerLast". > > I’m wondering why DependenceAnalysisWrapperPass is confused with this simple flow dependence. > If I’m misunderstanding about this dependence analysis, please correct me. > > Thanks, > Kento > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev