[llvm-commits] [PATCH][SOPT] Fix assertion in Reassociate
Shuxin Yang
shuxin.llvm at gmail.com
Mon Nov 5 22:47:08 PST 2012
This patch is to fix rdar://12571717, it is about assertion in
Reassociate pass.
Long story short, the assertion is trigged when the pass try to
transform expression
... + 2 * n * 3 + 2 * m + ...
into:
... + 2 * (n*3 + m).
In the process of the transformation, a helper routine folds the
constant 2*3 into 6,
confusing optimizer which is trying the to eliminate the common factor
2, and cannot
find 2 any more.
Weaken the assertion doesn't help, as the transformation is half done.
There are two ways to fix the probelm:
1) Ask the helper routine don't do better job, just do what it is
expected.
2) Walk the expression worklist in a order such that sub-expr is
visited prior to
the supper-expr. This way, 2*3 is already folded before the
super-expr is visited.
1) entails lots of change, 2) seems to be easier. It is just opposite:-(
I go for 2) not only because it seemed to be easier in the first place,
I think it is the right order to go through expressions being reassociated.
The testing case (reduced by bugpoint) for this probelm is not inclued
in the patch, as it
is too big.
Thanks
Shuxin
================================================================================
Worklist
========
The worklist WAS using SetVector. It was a container both for dead
instructions and
the expressions that could be optimized via reassociation. Exprs, no
matter dead code
or the those to be reassociated, are visited in FILO order.
I rewrite the worklist. The new worklist has following traits:
o. it is basically std::deque
o. has "set" semantic, akin to the SetVector. Unlike the setVector, the
set is implemented using std::map instead of SmallVector for
efficiency
purpose (In the case I'm working on, the worklist contains about
1.5k
instrucitons).
o. all dead instructions are eliminated in one loop: optimize
iterates the
worklist in *backward* order, identifying the dead code, and
removing them "in-place". The "in-place" removal is done by
invlaiding
the element instead of physically removing the space from the
worklist.
This way, it obviates the need of memory move, and avoid
invalidating
iterator.
o. the rest exprs are visited in forward order (i.e. FIFO)
This part is implemented using STL style. It is so odd to see
"PushBack" when
we are getting used to "push_back":-)
Other changes:
===============
The new worklist exposes some defects.
1. test/Transforms/Reassociate/multistep.ll
Without my change a*a*b+a*a*c was turned into a*(a*(b+c)); with my
change the result is (a*a)*(b+c). I don't know for sure if the
reassociator
intentionally choose tall-and-skinny expr tree in order to reduce
register pressure.
2. test/Transforms/Reassociate/mul_neg.ll (new)
The reassociator was not able to perform following simplifiction:
(-x) * c => x * -c ,
-x * -y => -x * -y
if the negations are used in multiple placess.
The optimization now is implemented by
Reassociate::removeNegFromMulOps().
Without this opt, we will see three regressions.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: diff.patch
Type: text/x-patch
Size: 13987 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20121105/df847165/attachment.bin>
More information about the llvm-commits
mailing list