diff options
author | Sumanth Gundapaneni <sgundapa@codeaurora.org> | 2018-10-11 19:48:15 +0000 |
---|---|---|
committer | Sumanth Gundapaneni <sgundapa@codeaurora.org> | 2018-10-11 19:48:15 +0000 |
commit | a4a9155e4fff5e8c427df0fbd465bce7a63fdfc4 (patch) | |
tree | a37c2a90ead41605958eedbff87f992451367f44 /llvm/lib/Target | |
parent | 77418a37537c42bb7db5f6b846aba15cfe2edf79 (diff) | |
download | bcm5719-llvm-a4a9155e4fff5e8c427df0fbd465bce7a63fdfc4.tar.gz bcm5719-llvm-a4a9155e4fff5e8c427df0fbd465bce7a63fdfc4.zip |
[Hexagon] Restrict compound instructions with constant value.
Having a constant value operand in the compound instruction
is not always profitable. This patch improves coremark by ~4% on
Hexagon.
Differential Revision: https://reviews.llvm.org/D53152
llvm-svn: 344284
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonPatterns.td | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonPatterns.td b/llvm/lib/Target/Hexagon/HexagonPatterns.td index 2f5033a20af..f671238ec12 100644 --- a/llvm/lib/Target/Hexagon/HexagonPatterns.td +++ b/llvm/lib/Target/Hexagon/HexagonPatterns.td @@ -257,6 +257,23 @@ class pf2<SDNode Op> : PatFrag<(ops node:$a, node:$b), (Op node:$a, node:$b)>; class Not2<PatFrag P> : PatFrag<(ops node:$A, node:$B), (P node:$A, (not node:$B))>; +// If there is a constant operand that feeds the and/or instruction, +// do not generate the compound instructions. +// It is not always profitable, as some times we end up with a transfer. +// Check the below example. +// ra = #65820; rb = lsr(rb, #8); rc ^= and (rb, ra) +// Instead this is preferable. +// ra = and (#65820, lsr(ra, #8)); rb = xor(rb, ra) +class Su_ni1<PatFrag Op> + : PatFrag<Op.Operands, !head(Op.Fragments), [{ + if (hasOneUse(N)){ + // Check if Op1 is an immediate operand. + SDValue Op1 = N->getOperand(1); + return !dyn_cast<ConstantSDNode>(Op1); + } + return false;}], + Op.OperandTransform>; + class Su<PatFrag Op> : PatFrag<Op.Operands, !head(Op.Fragments), [{ return hasOneUse(N); }], Op.OperandTransform>; @@ -1336,16 +1353,16 @@ def: Pat<(mul I32:$Rs, n8_0ImmPred:$n8), def: Pat<(add Sext64:$Rs, I64:$Rt), (A2_addsp (LoReg Sext64:$Rs), I64:$Rt)>; -def: AccRRR_pat<M4_and_and, And, Su<And>, I32, I32, I32>; -def: AccRRR_pat<M4_and_or, And, Su<Or>, I32, I32, I32>; -def: AccRRR_pat<M4_and_xor, And, Su<Xor>, I32, I32, I32>; -def: AccRRR_pat<M4_or_and, Or, Su<And>, I32, I32, I32>; -def: AccRRR_pat<M4_or_or, Or, Su<Or>, I32, I32, I32>; -def: AccRRR_pat<M4_or_xor, Or, Su<Xor>, I32, I32, I32>; -def: AccRRR_pat<M4_xor_and, Xor, Su<And>, I32, I32, I32>; -def: AccRRR_pat<M4_xor_or, Xor, Su<Or>, I32, I32, I32>; -def: AccRRR_pat<M2_xor_xacc, Xor, Su<Xor>, I32, I32, I32>; -def: AccRRR_pat<M4_xor_xacc, Xor, Su<Xor>, I64, I64, I64>; +def: AccRRR_pat<M4_and_and, And, Su_ni1<And>, I32, I32, I32>; +def: AccRRR_pat<M4_and_or, And, Su_ni1<Or>, I32, I32, I32>; +def: AccRRR_pat<M4_and_xor, And, Su<Xor>, I32, I32, I32>; +def: AccRRR_pat<M4_or_and, Or, Su_ni1<And>, I32, I32, I32>; +def: AccRRR_pat<M4_or_or, Or, Su_ni1<Or>, I32, I32, I32>; +def: AccRRR_pat<M4_or_xor, Or, Su<Xor>, I32, I32, I32>; +def: AccRRR_pat<M4_xor_and, Xor, Su_ni1<And>, I32, I32, I32>; +def: AccRRR_pat<M4_xor_or, Xor, Su_ni1<Or>, I32, I32, I32>; +def: AccRRR_pat<M2_xor_xacc, Xor, Su<Xor>, I32, I32, I32>; +def: AccRRR_pat<M4_xor_xacc, Xor, Su<Xor>, I64, I64, I64>; // For dags like (or (and (not _), _), (shl _, _)) where the "or" with // one argument matches the patterns below, and with the other argument |