[LLVMdev] Unexpected DSAnalysis behavior

John Criswell criswell at illinois.edu
Mon Mar 4 13:44:53 PST 2013


On 3/4/13 8:05 AM, Kevin Streit wrote:
> Hi,
>
> during the hunt for a bug causing strange behavior of our automatic 
> parallelization framework,
> I found some, at least for me, unexpected behavior of the 
> DataStructureAnalysis in Poolalloc.
>
> Consider the following simplified program:
>
> ====================
> int ARR[4] = {1, 2, 3, 4};
>
> int a(int pos) {
>     return ARR[pos];
> }
>
> int sum(int op_a, int op_b) {
>     return a(op_a) + a(op_b);
> }
>
> int main(int argc, const char *argv[]) {
>     return sum(1, 3);
> }
> ====================
>
> The unexpected behavior is that the bottum-up-graphs (and consequently 
> the top-down-graphs)
> of methods sum and main do not contain any hint on the read of the 
> global variable ARR. These
> graphs thus do not reflect the full effects of the methods, which I 
> expected them to do. (Screenshots attached)

You are correct that the graphs themselves do not reflect all the 
behaviors of callees, but that is not what the Bottom-Up (BU) pass in 
DSA is supposed to do.  If it did that, then the main() function would 
be an unwieldy DSGraph that described every memory object in the program.

In BU, each function has a DSGraph that summarizes what the function and 
its callees do to the memory objects that are reachable from within that 
function.  In your example, main() and sum() do not have any SSA 
register values that point to any memory objects, nor do they use any 
global SSA registers that could point to a memory object.  As a result, 
their DSGraph contains no memory objects.

If you modified the program to be something like:

int ARR[4] = {1, 2, 3, 4};

int a(int * arr, int pos) {
     return arr[pos];
}

int sum(int * arr, int op_a, int op_b) {
     return a(arr, op_a) + a(arr, op_b);
}

int main(int argc, const char *argv[]) {
     return sum(ARR, 1, 3);
}

... then the DSGraphs for main() and sum() should show an SSA register 
that points to a global memory object, and the flags on that memory 
object should reflect what the callees do on that memory object.

If you want to find all the abstract memory objects which a function and 
its callees could modify, even if the memory object isn't reachable from 
the given function, you're going to have to traverse the call graph and 
collect all the DSNodes within each one.  You may also have to match up 
the caller/callee DSNodes for each function call.

-- John T.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130304/5efdfd37/attachment.html>


More information about the llvm-dev mailing list