Hi Chris, I took a haste look at the "Points-to Analysis in Almost Linear Time" by Steens , your PHD thesis and SteensGaard.cpp in LLVM this afternoon. So I think: 1. Actually the basic algorithm described originally by SteensGaard does not provide MOD/REF information for functions. 2. The context insensitive part of Data Structure Analysis (LocalAnalysis) can be deemed as an enhancement of Steens' with field sensitive and MOD/REF information 3. The implementation of -steens-aa in LLVM is through Data Structure Analysis with MOD/REF logic for functions as below: i. inComplete nodes may MODREF by all function. ii. external function does not MOD/REF any complete node. iii if any function MOD/REF a node then all function considered as MOD/REF the node. In other words, if I only use -steens-aa and the data_XXXs are all external global variables( and so inComplete ), the call to printf will make the same effect, which I have tested it. Am I right ? :) On Monday 15 May 2006 12:52, Chris Lattner wrote:> On Mon, 15 May 2006, Nai Xia wrote: > > Thank you very much for your detailed help. > > You are definitely a good man. :) > > I feel so much to learn. > > Happy to help! > > -Chris > > > On Monday 15 May 2006 04:07, you wrote: > >> On Sun, 14 May 2006, Nai XIA wrote: > >>> Oh, I appologize that I should not have asked about __main() ---- it appears > >>> in FAQ. > >>> But the question remains that why call to __main() can alias stack location? > >>> I think the memory location pointed by data_X pointers are not visible to > >>> __main(). > >>> In comparison, calls to printf() do not have similar effect. > >> > >> First, some background: -steens-aa and -anders-aa work reasonable well, > >> but aren't production quality. In particular, they both assume that > >> printf doesn't have side effects, when (in fact) printf can on certain GNU > >> systems when the right format string is used. This is why they both think > >> that printf has no side effects: they special case it. > >> > >> In practice, aliasing is a bunch of heuristics, and you cannot ever be > >> guaranteed to get an exact answer. As an example of this, both of these > >> passes are "context insensitive". As such, they don't know anything about > >> what the effect of a call is, so the call to __main (even though they > >> could theoretically know) is treated quite conservatively. > >> > >> There are a couple of different options you have here. The alias passes > >> can be combined together, so something like this: > >> > >> opt -globalsmodref-aa -steens-aa ... > >> > >> should be able to tell that __main has no side effects. globalsmodref-aa > >> is a production quality pass that does some simple context sensitive > >> analysis (such as noticing functions with no side effects at all). > >> > >> Another option is the -ds-aa pass. This pass is very powerful, but is > >> also the farthest from production quality. That said, it does get almost > >> all common things right, it just has some bugs in areas like variable > >> length arrays etc. > >> > >> -Chris > >> > >> > >>> On 5/14/06, Nai Xia <nelson.xia at gmail.com> wrote: > >>>> > >>>> In a code segment of my pass plugin, I try to gather AliasSets for all > >>>> StoreInst, LoadInst and CallInst instructions in a function. > >>>> Some behaviors of the pass puzzled me. > >>>> Below is the *.ll of the test program which I run the pass on, > >>>> it was get with "llvm-gcc -Wl,--disable-opt" from a rather simple *.c > >>>> program. > >>>> > >>>> ---------------------------------- > >>>> ; ModuleID = 'ptralias.bc' > >>>> target endian = little > >>>> target pointersize = 32 > >>>> target triple = "i686-pc-linux-gnu" > >>>> deplibs = [ "c", "crtend" ] > >>>> %.str_1 = internal constant [25 x sbyte] c"ptra=0x ptrb=0x > >>>> ptrc=0x\0A\00" ; <[25 x sbyte]*> [#uses=1] > >>>> %ptr = weak global void ()* null ; <void ()**> [#uses=0] > >>>> > >>>> implementation ; Functions: > >>>> > >>>> declare int %printf(sbyte*, ...) > >>>> > >>>> void %foo1() { > >>>> ret void > >>>> } > >>>> > >>>> void %foo2() { > >>>> ret void > >>>> } > >>>> > >>>> int %main(int %argc, sbyte** %argv) { > >>>> entry: > >>>> %data_b = alloca int ; <int*> [#uses=2] > >>>> %data_c = alloca int ; <int*> [#uses=1] > >>>> %data_d = alloca int ; <int*> [#uses=3] > >>>> %data_e = alloca int ; <int*> [#uses=2] > >>>> %data_f = alloca int ; <int*> [#uses=2] > >>>> call void %__main( ) > >>>> store int 2, int* %data_b > >>>> store int 3, int* %data_c > >>>> store int 4, int* %data_d > >>>> store int 5, int* %data_e > >>>> store int 6, int* %data_f > >>>> switch int %argc, label %switchexit [ > >>>> int 3, label %label.3 > >>>> int 2, label %then.2 > >>>> int 1, label %label.1 > >>>> int 0, label %endif.2 > >>>> ] > >>>> > >>>> label.1: ; preds = %entry > >>>> br label %switchexit > >>>> > >>>> label.3: ; preds = %entry > >>>> br label %then.2 > >>>> > >>>> switchexit: ; preds = %label.1, %entry > >>>> %ptr_b.0 = phi int* [ %data_d, %label.1 ], [ null, %entry ] ; > >>>> <int*> [#uses=1] > >>>> br label %endif.2 > >>>> > >>>> then.2: ; preds = %label.3, %entry > >>>> %ptr_a.1.0 = phi int* [ %data_f, %label.3 ], [ %data_e, %entry > >>>> ] ; <int*> [#uses=1] > >>>> store int 0, int* %ptr_a.1.0 > >>>> br label %then.3 > >>>> > >>>> endif.2: ; preds = %switchexit, %entry > >>>> %ptr_b.0.1 = phi int* [ %ptr_b.0, %switchexit ], [ %data_b, %entry > >>>> ] ; <int*> [#uses=2] > >>>> %tmp.12 = seteq int* %ptr_b.0.1, null ; <bool> [#uses=1] > >>>> br bool %tmp.12, label %then.4, label %then.3 > >>>> > >>>> then.3: ; preds = %endif.2, %then.2 > >>>> %ptr_b.0.2 = phi int* [ %data_d, %then.2 ], [ %ptr_b.0.1, %endif.2 > >>>> ] ; <int*> [#uses=1] > >>>> store int 0, int* %ptr_b.0.2 > >>>> %tmp.1913 = call int (sbyte*, ...)* %printf( sbyte* getelementptr > >>>> ([25 x sbyte]* %.str_1, int 0, int 0) ) ; <int> [#uses=0] > >>>> ret int 0 > >>>> > >>>> then.4: ; preds = %endif.2 > >>>> %tmp.19 = call int (sbyte*, ...)* %printf( sbyte* getelementptr > >>>> ([25 x sbyte]* %.str_1, int 0, int 0) ) ; <int> [#uses=0] > >>>> ret int 0 > >>>> } > >>>> > >>>> void %__main() { > >>>> entry: > >>>> ret void > >>>> } > >>>> > >>>> ---------------------------------- > >>>> I think the right AliasSet information calculated for this program should > >>>> be > >>>> > >>>> Information for alias set0: > >>>> pointer0=data_b > >>>> pointer1=data_d > >>>> pointer2=ptr_b.0.2 > >>>> Information for alias set1: > >>>> pointer0=data_c > >>>> Information for alias set2: > >>>> Information for alias set3: > >>>> pointer0=data_e > >>>> pointer1=data_f > >>>> pointer2=ptr_a.1.0 > >>>> Information for alias set4: > >>>> Information for alias set5: > >>>> > >>>> ,where the empty AliasSets I think should be "Forwarded". > >>>> > >>>> However, the result of the pass was: > >>>> > >>>> Information for alias set0: > >>>> pointer0=data_b > >>>> pointer1=data_d > >>>> pointer2=data_e > >>>> pointer3=data_f > >>>> pointer4=ptr_a.1.0 > >>>> pointer5=ptr_b.0.2 > >>>> Information for alias set1: > >>>> pointer0=data_c > >>>> After I deleted "call void %__main( )" in %main(), the pass get the right > >>>> answer. > >>>> > >>>> So my question is: > >>>> > >>>> 1. What is the purpose for call to __main() ? __main() is just a empty > >>>> function. My .c program only contains main(). > >>>> 2. My explanation for this behavior is that the CallSite of "call void > >>>> %__main( )" alias some pointers in the program, > >>>> however, __main() is obviously empty, why should the AliasAnalysis > >>>> think that it may/must Mod/Ref any stack location of main()? > >>>> > >>>> btw: the AliasAnalysis pass I used is -steens-aa and it also the same with > >>>> -anders-aa. > >>>> > >>>> -- > >>>> Regards, > >>>> Nai > >>>> > >>> > >> > >> -Chris > >> > > > > > > -Chris >-- Regards, Nai
On Mon, 15 May 2006, Nai Xia wrote:> In other words, if I only use -steens-aa and the data_XXXs are all > external global variables( and so inComplete ),Sounds right!> the call to printf will > make the same effect, which I have tested it. > > Am I right ? :)If you've tested it then, yes you're right :). I haven't played with this stuff for a long time, but I was pretty sure that steens-aa and ds-aa had a special case for printf so that it thinks that printf does not mod/ref *anything*, including external globals. My guess is that steens-aa gives up earlier because it's an external global and it's an external function call or something. You'd have to trace through the logic of the code to be sure. -Chris> On Monday 15 May 2006 12:52, Chris Lattner wrote: >> On Mon, 15 May 2006, Nai Xia wrote: >>> Thank you very much for your detailed help. >>> You are definitely a good man. :) >>> I feel so much to learn. >> >> Happy to help! >> >> -Chris >> >>> On Monday 15 May 2006 04:07, you wrote: >>>> On Sun, 14 May 2006, Nai XIA wrote: >>>>> Oh, I appologize that I should not have asked about __main() ---- it appears >>>>> in FAQ. >>>>> But the question remains that why call to __main() can alias stack location? >>>>> I think the memory location pointed by data_X pointers are not visible to >>>>> __main(). >>>>> In comparison, calls to printf() do not have similar effect. >>>> >>>> First, some background: -steens-aa and -anders-aa work reasonable well, >>>> but aren't production quality. In particular, they both assume that >>>> printf doesn't have side effects, when (in fact) printf can on certain GNU >>>> systems when the right format string is used. This is why they both think >>>> that printf has no side effects: they special case it. >>>> >>>> In practice, aliasing is a bunch of heuristics, and you cannot ever be >>>> guaranteed to get an exact answer. As an example of this, both of these >>>> passes are "context insensitive". As such, they don't know anything about >>>> what the effect of a call is, so the call to __main (even though they >>>> could theoretically know) is treated quite conservatively. >>>> >>>> There are a couple of different options you have here. The alias passes >>>> can be combined together, so something like this: >>>> >>>> opt -globalsmodref-aa -steens-aa ... >>>> >>>> should be able to tell that __main has no side effects. globalsmodref-aa >>>> is a production quality pass that does some simple context sensitive >>>> analysis (such as noticing functions with no side effects at all). >>>> >>>> Another option is the -ds-aa pass. This pass is very powerful, but is >>>> also the farthest from production quality. That said, it does get almost >>>> all common things right, it just has some bugs in areas like variable >>>> length arrays etc. >>>> >>>> -Chris >>>> >>>> >>>>> On 5/14/06, Nai Xia <nelson.xia at gmail.com> wrote: >>>>>> >>>>>> In a code segment of my pass plugin, I try to gather AliasSets for all >>>>>> StoreInst, LoadInst and CallInst instructions in a function. >>>>>> Some behaviors of the pass puzzled me. >>>>>> Below is the *.ll of the test program which I run the pass on, >>>>>> it was get with "llvm-gcc -Wl,--disable-opt" from a rather simple *.c >>>>>> program. >>>>>> >>>>>> ---------------------------------- >>>>>> ; ModuleID = 'ptralias.bc' >>>>>> target endian = little >>>>>> target pointersize = 32 >>>>>> target triple = "i686-pc-linux-gnu" >>>>>> deplibs = [ "c", "crtend" ] >>>>>> %.str_1 = internal constant [25 x sbyte] c"ptra=0x ptrb=0x >>>>>> ptrc=0x\0A\00" ; <[25 x sbyte]*> [#uses=1] >>>>>> %ptr = weak global void ()* null ; <void ()**> [#uses=0] >>>>>> >>>>>> implementation ; Functions: >>>>>> >>>>>> declare int %printf(sbyte*, ...) >>>>>> >>>>>> void %foo1() { >>>>>> ret void >>>>>> } >>>>>> >>>>>> void %foo2() { >>>>>> ret void >>>>>> } >>>>>> >>>>>> int %main(int %argc, sbyte** %argv) { >>>>>> entry: >>>>>> %data_b = alloca int ; <int*> [#uses=2] >>>>>> %data_c = alloca int ; <int*> [#uses=1] >>>>>> %data_d = alloca int ; <int*> [#uses=3] >>>>>> %data_e = alloca int ; <int*> [#uses=2] >>>>>> %data_f = alloca int ; <int*> [#uses=2] >>>>>> call void %__main( ) >>>>>> store int 2, int* %data_b >>>>>> store int 3, int* %data_c >>>>>> store int 4, int* %data_d >>>>>> store int 5, int* %data_e >>>>>> store int 6, int* %data_f >>>>>> switch int %argc, label %switchexit [ >>>>>> int 3, label %label.3 >>>>>> int 2, label %then.2 >>>>>> int 1, label %label.1 >>>>>> int 0, label %endif.2 >>>>>> ] >>>>>> >>>>>> label.1: ; preds = %entry >>>>>> br label %switchexit >>>>>> >>>>>> label.3: ; preds = %entry >>>>>> br label %then.2 >>>>>> >>>>>> switchexit: ; preds = %label.1, %entry >>>>>> %ptr_b.0 = phi int* [ %data_d, %label.1 ], [ null, %entry ] ; >>>>>> <int*> [#uses=1] >>>>>> br label %endif.2 >>>>>> >>>>>> then.2: ; preds = %label.3, %entry >>>>>> %ptr_a.1.0 = phi int* [ %data_f, %label.3 ], [ %data_e, %entry >>>>>> ] ; <int*> [#uses=1] >>>>>> store int 0, int* %ptr_a.1.0 >>>>>> br label %then.3 >>>>>> >>>>>> endif.2: ; preds = %switchexit, %entry >>>>>> %ptr_b.0.1 = phi int* [ %ptr_b.0, %switchexit ], [ %data_b, %entry >>>>>> ] ; <int*> [#uses=2] >>>>>> %tmp.12 = seteq int* %ptr_b.0.1, null ; <bool> [#uses=1] >>>>>> br bool %tmp.12, label %then.4, label %then.3 >>>>>> >>>>>> then.3: ; preds = %endif.2, %then.2 >>>>>> %ptr_b.0.2 = phi int* [ %data_d, %then.2 ], [ %ptr_b.0.1, %endif.2 >>>>>> ] ; <int*> [#uses=1] >>>>>> store int 0, int* %ptr_b.0.2 >>>>>> %tmp.1913 = call int (sbyte*, ...)* %printf( sbyte* getelementptr >>>>>> ([25 x sbyte]* %.str_1, int 0, int 0) ) ; <int> [#uses=0] >>>>>> ret int 0 >>>>>> >>>>>> then.4: ; preds = %endif.2 >>>>>> %tmp.19 = call int (sbyte*, ...)* %printf( sbyte* getelementptr >>>>>> ([25 x sbyte]* %.str_1, int 0, int 0) ) ; <int> [#uses=0] >>>>>> ret int 0 >>>>>> } >>>>>> >>>>>> void %__main() { >>>>>> entry: >>>>>> ret void >>>>>> } >>>>>> >>>>>> ---------------------------------- >>>>>> I think the right AliasSet information calculated for this program should >>>>>> be >>>>>> >>>>>> Information for alias set0: >>>>>> pointer0=data_b >>>>>> pointer1=data_d >>>>>> pointer2=ptr_b.0.2 >>>>>> Information for alias set1: >>>>>> pointer0=data_c >>>>>> Information for alias set2: >>>>>> Information for alias set3: >>>>>> pointer0=data_e >>>>>> pointer1=data_f >>>>>> pointer2=ptr_a.1.0 >>>>>> Information for alias set4: >>>>>> Information for alias set5: >>>>>> >>>>>> ,where the empty AliasSets I think should be "Forwarded". >>>>>> >>>>>> However, the result of the pass was: >>>>>> >>>>>> Information for alias set0: >>>>>> pointer0=data_b >>>>>> pointer1=data_d >>>>>> pointer2=data_e >>>>>> pointer3=data_f >>>>>> pointer4=ptr_a.1.0 >>>>>> pointer5=ptr_b.0.2 >>>>>> Information for alias set1: >>>>>> pointer0=data_c >>>>>> After I deleted "call void %__main( )" in %main(), the pass get the right >>>>>> answer. >>>>>> >>>>>> So my question is: >>>>>> >>>>>> 1. What is the purpose for call to __main() ? __main() is just a empty >>>>>> function. My .c program only contains main(). >>>>>> 2. My explanation for this behavior is that the CallSite of "call void >>>>>> %__main( )" alias some pointers in the program, >>>>>> however, __main() is obviously empty, why should the AliasAnalysis >>>>>> think that it may/must Mod/Ref any stack location of main()? >>>>>> >>>>>> btw: the AliasAnalysis pass I used is -steens-aa and it also the same with >>>>>> -anders-aa. >>>>>> >>>>>> -- >>>>>> Regards, >>>>>> Nai >>>>>> >>>>> >>>> >>>> -Chris >>>> >>> >>> >> >> -Chris >> > >-Chris -- http://nondot.org/sabre/ http://llvm.org/
On Tuesday 16 May 2006 03:19, Chris Lattner wrote:> On Mon, 15 May 2006, Nai Xia wrote: > > > In other words, if I only use -steens-aa and the data_XXXs are all > > external global variables( and so inComplete ), > > Sounds right! > > > the call to printf will > > make the same effect, which I have tested it. > > > > Am I right ? :) > > If you've tested it then, yes you're right :). I haven't played with this > stuff for a long time, but I was pretty sure that steens-aa and ds-aa had > a special case for printf so that it thinks that printf does not mod/ref > *anything*, including external globals.Unfortunately, I did not locate the lines in steens-aa for "printf" special case. In ds-aa, I found the lines below: -------------------------------- if (F->getName() == "printf" || F->getName() == "fprintf" || F->getName() == "sprintf") { CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end(); if (F->getName() == "fprintf") { // fprintf reads and writes the FILE argument, and applies the type // to it. DSNodeHandle H = getValueDest(**AI); if (DSNode *N = H.getNode()) { N->setModifiedMarker(); const Type *ArgTy = (*AI)->getType(); if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy)) N->mergeTypeInfo(PTy->getElementType(), H.getOffset()); } } else if (F->getName() == "sprintf") { // sprintf writes the first string argument. DSNodeHandle H = getValueDest(**AI++); if (DSNode *N = H.getNode()) { N->setModifiedMarker(); const Type *ArgTy = (*AI)->getType(); if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy)) N->mergeTypeInfo(PTy->getElementType(), H.getOffset()); } } for (; AI != E; ++AI) { // printf reads all pointer arguments. if (isPointerType((*AI)->getType())) if (DSNode *N = getValueDest(**AI).getNode()) N->setReadMarker(); } ----------------------------- So from my point of view, the ds-aa thinks "printf reads all pointer arguments", but does not take into account the "%n" format string , which may cause "printf" MOD to a specific address. As for steens-aa, I think the logic for mod/ref is very clear: --------------------- AliasAnalysis::ModRefResult Steens::getModRefInfo(CallSite CS, Value *P, unsigned Size) { AliasAnalysis::ModRefResult Result = ModRef; // Find the node in question. DSGraph::ScalarMapTy &GSM = ResultGraph->getScalarMap(); DSGraph::ScalarMapTy::iterator I = GSM.find(P); if (I != GSM.end() && !I->second.isNull()) { DSNode *N = I->second.getNode(); if (N->isComplete()) { // If this is a direct call to an external function, and if the pointer // points to a complete node, the external function cannot modify or read // the value (we know it's not passed out of the program!). if (Function *F = CS.getCalledFunction()) if (F->isExternal()) return NoModRef; // Otherwise, if the node is complete, but it is only M or R, return this. // This can be useful for globals that should be marked const but are not. if (!N->isModified()) Result = (ModRefResult)(Result & ~Mod); if (!N->isRead()) Result = (ModRefResult)(Result & ~Ref); } } return (ModRefResult)(Result & AliasAnalysis::getModRefInfo(CS, P, Size)); } --------------------- So steens-aa alone thinks "printf" ModRef *anything* that is inComplete(e.g. external globalVar) . Did I missed anything? Again, thanks for your patience :)> > My guess is that steens-aa gives up earlier because it's an external > global and it's an external function call or something. You'd have to > trace through the logic of the code to be sure. > > -Chris > > > On Monday 15 May 2006 12:52, Chris Lattner wrote: > >> On Mon, 15 May 2006, Nai Xia wrote: > >>> Thank you very much for your detailed help. > >>> You are definitely a good man. :) > >>> I feel so much to learn. > >> > >> Happy to help! > >> > >> -Chris > >> > >>> On Monday 15 May 2006 04:07, you wrote: > >>>> On Sun, 14 May 2006, Nai XIA wrote: > >>>>> Oh, I appologize that I should not have asked about __main() ---- it appears > >>>>> in FAQ. > >>>>> But the question remains that why call to __main() can alias stack location? > >>>>> I think the memory location pointed by data_X pointers are not visible to > >>>>> __main(). > >>>>> In comparison, calls to printf() do not have similar effect. > >>>> > >>>> First, some background: -steens-aa and -anders-aa work reasonable well, > >>>> but aren't production quality. In particular, they both assume that > >>>> printf doesn't have side effects, when (in fact) printf can on certain GNU > >>>> systems when the right format string is used. This is why they both think > >>>> that printf has no side effects: they special case it. > >>>> > >>>> In practice, aliasing is a bunch of heuristics, and you cannot ever be > >>>> guaranteed to get an exact answer. As an example of this, both of these > >>>> passes are "context insensitive". As such, they don't know anything about > >>>> what the effect of a call is, so the call to __main (even though they > >>>> could theoretically know) is treated quite conservatively. > >>>> > >>>> There are a couple of different options you have here. The alias passes > >>>> can be combined together, so something like this: > >>>> > >>>> opt -globalsmodref-aa -steens-aa ... > >>>> > >>>> should be able to tell that __main has no side effects. globalsmodref-aa > >>>> is a production quality pass that does some simple context sensitive > >>>> analysis (such as noticing functions with no side effects at all). > >>>> > >>>> Another option is the -ds-aa pass. This pass is very powerful, but is > >>>> also the farthest from production quality. That said, it does get almost > >>>> all common things right, it just has some bugs in areas like variable > >>>> length arrays etc. > >>>> > >>>> -Chris > >>>> > >>>> > >>>>> On 5/14/06, Nai Xia <nelson.xia at gmail.com> wrote: > >>>>>> > >>>>>> In a code segment of my pass plugin, I try to gather AliasSets for all > >>>>>> StoreInst, LoadInst and CallInst instructions in a function. > >>>>>> Some behaviors of the pass puzzled me. > >>>>>> Below is the *.ll of the test program which I run the pass on, > >>>>>> it was get with "llvm-gcc -Wl,--disable-opt" from a rather simple *.c > >>>>>> program. > >>>>>> > >>>>>> ---------------------------------- > >>>>>> ; ModuleID = 'ptralias.bc' > >>>>>> target endian = little > >>>>>> target pointersize = 32 > >>>>>> target triple = "i686-pc-linux-gnu" > >>>>>> deplibs = [ "c", "crtend" ] > >>>>>> %.str_1 = internal constant [25 x sbyte] c"ptra=0x ptrb=0x > >>>>>> ptrc=0x\0A\00" ; <[25 x sbyte]*> [#uses=1] > >>>>>> %ptr = weak global void ()* null ; <void ()**> [#uses=0] > >>>>>> > >>>>>> implementation ; Functions: > >>>>>> > >>>>>> declare int %printf(sbyte*, ...) > >>>>>> > >>>>>> void %foo1() { > >>>>>> ret void > >>>>>> } > >>>>>> > >>>>>> void %foo2() { > >>>>>> ret void > >>>>>> } > >>>>>> > >>>>>> int %main(int %argc, sbyte** %argv) { > >>>>>> entry: > >>>>>> %data_b = alloca int ; <int*> [#uses=2] > >>>>>> %data_c = alloca int ; <int*> [#uses=1] > >>>>>> %data_d = alloca int ; <int*> [#uses=3] > >>>>>> %data_e = alloca int ; <int*> [#uses=2] > >>>>>> %data_f = alloca int ; <int*> [#uses=2] > >>>>>> call void %__main( ) > >>>>>> store int 2, int* %data_b > >>>>>> store int 3, int* %data_c > >>>>>> store int 4, int* %data_d > >>>>>> store int 5, int* %data_e > >>>>>> store int 6, int* %data_f > >>>>>> switch int %argc, label %switchexit [ > >>>>>> int 3, label %label.3 > >>>>>> int 2, label %then.2 > >>>>>> int 1, label %label.1 > >>>>>> int 0, label %endif.2 > >>>>>> ] > >>>>>> > >>>>>> label.1: ; preds = %entry > >>>>>> br label %switchexit > >>>>>> > >>>>>> label.3: ; preds = %entry > >>>>>> br label %then.2 > >>>>>> > >>>>>> switchexit: ; preds = %label.1, %entry > >>>>>> %ptr_b.0 = phi int* [ %data_d, %label.1 ], [ null, %entry ] ; > >>>>>> <int*> [#uses=1] > >>>>>> br label %endif.2 > >>>>>> > >>>>>> then.2: ; preds = %label.3, %entry > >>>>>> %ptr_a.1.0 = phi int* [ %data_f, %label.3 ], [ %data_e, %entry > >>>>>> ] ; <int*> [#uses=1] > >>>>>> store int 0, int* %ptr_a.1.0 > >>>>>> br label %then.3 > >>>>>> > >>>>>> endif.2: ; preds = %switchexit, %entry > >>>>>> %ptr_b.0.1 = phi int* [ %ptr_b.0, %switchexit ], [ %data_b, %entry > >>>>>> ] ; <int*> [#uses=2] > >>>>>> %tmp.12 = seteq int* %ptr_b.0.1, null ; <bool> [#uses=1] > >>>>>> br bool %tmp.12, label %then.4, label %then.3 > >>>>>> > >>>>>> then.3: ; preds = %endif.2, %then.2 > >>>>>> %ptr_b.0.2 = phi int* [ %data_d, %then.2 ], [ %ptr_b.0.1, %endif.2 > >>>>>> ] ; <int*> [#uses=1] > >>>>>> store int 0, int* %ptr_b.0.2 > >>>>>> %tmp.1913 = call int (sbyte*, ...)* %printf( sbyte* getelementptr > >>>>>> ([25 x sbyte]* %.str_1, int 0, int 0) ) ; <int> [#uses=0] > >>>>>> ret int 0 > >>>>>> > >>>>>> then.4: ; preds = %endif.2 > >>>>>> %tmp.19 = call int (sbyte*, ...)* %printf( sbyte* getelementptr > >>>>>> ([25 x sbyte]* %.str_1, int 0, int 0) ) ; <int> [#uses=0] > >>>>>> ret int 0 > >>>>>> } > >>>>>> > >>>>>> void %__main() { > >>>>>> entry: > >>>>>> ret void > >>>>>> } > >>>>>> > >>>>>> ---------------------------------- > >>>>>> I think the right AliasSet information calculated for this program should > >>>>>> be > >>>>>> > >>>>>> Information for alias set0: > >>>>>> pointer0=data_b > >>>>>> pointer1=data_d > >>>>>> pointer2=ptr_b.0.2 > >>>>>> Information for alias set1: > >>>>>> pointer0=data_c > >>>>>> Information for alias set2: > >>>>>> Information for alias set3: > >>>>>> pointer0=data_e > >>>>>> pointer1=data_f > >>>>>> pointer2=ptr_a.1.0 > >>>>>> Information for alias set4: > >>>>>> Information for alias set5: > >>>>>> > >>>>>> ,where the empty AliasSets I think should be "Forwarded". > >>>>>> > >>>>>> However, the result of the pass was: > >>>>>> > >>>>>> Information for alias set0: > >>>>>> pointer0=data_b > >>>>>> pointer1=data_d > >>>>>> pointer2=data_e > >>>>>> pointer3=data_f > >>>>>> pointer4=ptr_a.1.0 > >>>>>> pointer5=ptr_b.0.2 > >>>>>> Information for alias set1: > >>>>>> pointer0=data_c > >>>>>> After I deleted "call void %__main( )" in %main(), the pass get the right > >>>>>> answer. > >>>>>> > >>>>>> So my question is: > >>>>>> > >>>>>> 1. What is the purpose for call to __main() ? __main() is just a empty > >>>>>> function. My .c program only contains main(). > >>>>>> 2. My explanation for this behavior is that the CallSite of "call void > >>>>>> %__main( )" alias some pointers in the program, > >>>>>> however, __main() is obviously empty, why should the AliasAnalysis > >>>>>> think that it may/must Mod/Ref any stack location of main()? > >>>>>> > >>>>>> btw: the AliasAnalysis pass I used is -steens-aa and it also the same with > >>>>>> -anders-aa. > >>>>>> > >>>>>> -- > >>>>>> Regards, > >>>>>> Nai > >>>>>> > >>>>> > >>>> > >>>> -Chris > >>>> > >>> > >>> > >> > >> -Chris > >> > > > > > > -Chris >-- Regards, Nai