[llvm-commits] [PATCH] Fix nondeterministic codegen in stack-coloring pass
Ulrich Weigand
Ulrich.Weigand at de.ibm.com
Thu Nov 15 11:25:18 PST 2012
Hello,
in my attempts to complete a "bootstrap" of clang on PowerPC, I'm still
running into spurious differences between the stage-2 and stage-3 compiler
binaries. One large set of such differences was due to different
assignments of variables to stack slots. It turns out that this happens in
the stack-coloring pass (CodeGen/StackColoring.cpp). In one example, that
pass was merging stack slots like this (in the stage-2 binary):
frame index 0 --> merged into frame index 30
frame index 1 --> merged into frame index 25
In the stage-3 binary we have instead:
frame index 0 --> merged into frame index 25
frame index 1 --> merged into frame index 30
Comparing the machine instruction dumps after the stack-coloring pass
shows:
Predecessors according to CFG: BB#156
%vreg573<def> = LD 10, %vreg192; mem:LD8[<unknown>]
G8RC:%vreg573,%vreg192
STD %vreg573<kill>, 0, <fi#26>; mem:ST8
[%ReadersWriters.i.i](tbaa=!"any pointer") G8RC:%vreg573
- STD %vreg126, 0, <fi#30>; mem:ST8[%Readers.i](tbaa=!"any pointer")
G8RC:%vreg126
- STD %vreg125, 0, <fi#25>; mem:ST8
[%AllocRelatedValues.i.i](tbaa=!"any pointer") G8RC:%vreg125
- %vreg574<def> = LD 0, <fi#30>; mem:LD8[<unknown>] G8RC:%vreg574
+ STD %vreg126, 0, <fi#25>; mem:ST8
[%AllocRelatedValues.i.i](tbaa=!"any pointer") G8RC:%vreg126
+ STD %vreg125, 0, <fi#30>; mem:ST8[%Readers.i](tbaa=!"any pointer")
G8RC:%vreg125
+ %vreg574<def> = LD 0, <fi#25>; mem:LD8[<unknown>] G8RC:%vreg574
STD %vreg574<kill>, 14, %X1; mem:ST8[<unknown>] G8RC:%vreg574
- %vreg575<def> = LD 0, <fi#25>; mem:LD8[<unknown>] G8RC:%vreg575
+ %vreg575<def> = LD 0, <fi#30>; mem:LD8[<unknown>] G8RC:%vreg575
STD %vreg575<kill>, 16, %X1; mem:ST8[<unknown>] G8RC:%vreg575
ADJCALLSTACKDOWN 112, %R1<imp-def,dead>, %R1<imp-use>
%vreg576<def> = LBZ8 0, <fi#23>; mem:LD1[<unknown>](align=8)
G8RC:%vreg576
- %vreg577<def> = LD 0, <fi#25>; mem:LD8[<unknown>] G8RC:%vreg577
- %vreg578<def> = LD 0, <fi#30>; mem:LD8[<unknown>] G8RC:%vreg578
+ %vreg577<def> = LD 0, <fi#30>; mem:LD8[<unknown>] G8RC:%vreg577
+ %vreg578<def> = LD 0, <fi#25>; mem:LD8[<unknown>] G8RC:%vreg578
%vreg579<def> = ADDI8 <fi#28>, 0; G8RC:%vreg579
%vreg580<def> = ADDI8 <fi#26>, 0; G8RC:%vreg580
%X3<def> = COPY %vreg579; G8RC:%vreg579
The reason for this difference is this piece of code:
// This is a simple greedy algorithm for merging allocas. First, sort the
// slots, placing the largest slots first. Next, perform an n^2 scan and
look
// for disjoint slots. When you find disjoint slots, merge the samller
one
// into the bigger one and update the live interval. Remove the small
alloca
// and continue.
// Sort the slots according to their size. Place unused slots at the end.
std::sort(SortedSlots.begin(), SortedSlots.end(), SlotSizeSorter(MFI));
In general, there may be many stack slots of the same size, so the sort
order imposed by SlotSizeSorter is not total. In such cases, std::sort has
nondeterministic output. These differences in the sorted array then lead
to corresponding differences in choices of stack slots to merge.
The attached patch fixes this by using std::stable_sort instead.
Tested on powerpc64-linux with no regressions in test/ or
projects/test-suite/. Fixes the vast majority of code differences between
stage-2 and stage-3 in a bootstrap on PowerPC (there are still two
unrelated differences left).
OK to commit?
Bye,
Ulrich
(See attached file: diff-llvm-stackslot-stablesort)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: diff-llvm-stackslot-stablesort
Type: application/octet-stream
Size: 614 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20121115/1f7469e0/attachment.obj>
More information about the llvm-commits
mailing list