summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/CodeGenPrepare.cpp
diff options
context:
space:
mode:
authorJames Molloy <james.molloy@arm.com>2016-01-15 09:20:19 +0000
committerJames Molloy <james.molloy@arm.com>2016-01-15 09:20:19 +0000
commitf01488e2bc76f143684be686ed118343cf8da74e (patch)
treea5d59aa8aa57f06e03fbaabbac8d3d333750c050 /llvm/lib/CodeGen/CodeGenPrepare.cpp
parent5b29e096acb1b2d8593fe40eefd88e44871a3f2a (diff)
downloadbcm5719-llvm-f01488e2bc76f143684be686ed118343cf8da74e.tar.gz
bcm5719-llvm-f01488e2bc76f143684be686ed118343cf8da74e.zip
[InstCombine] Rewrite bswap/bitreverse handling completely.
There are several requirements that ended up with this design; 1. Matching bitreversals is too heavyweight for InstCombine and doesn't really need to be done so early. 2. Bitreversals and byteswaps are very related in their matching logic. 3. We want to implement support for matching more advanced bswap/bitreverse patterns like partial bswaps/bitreverses. 4. Bswaps are best matched early in InstCombine. The result of these is that a new utility function is created in Transforms/Utils/Local.h that can be configured to search for bswaps, bitreverses or both. InstCombine uses it to find only bswaps, CGP uses it to find only bitreversals. We can then extend the matching logic in one place only. llvm-svn: 257875
Diffstat (limited to 'llvm/lib/CodeGen/CodeGenPrepare.cpp')
-rw-r--r--llvm/lib/CodeGen/CodeGenPrepare.cpp29
1 files changed, 29 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 03e57787307..4326ba99538 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -5211,6 +5211,24 @@ bool CodeGenPrepare::optimizeInst(Instruction *I, bool& ModifiedDT) {
return false;
}
+/// Given an OR instruction, check to see if this is a bitreverse
+/// idiom. If so, insert the new intrinsic and return true.
+static bool makeBitReverse(Instruction &I, const DataLayout &DL,
+ const TargetLowering &TLI) {
+ if (!I.getType()->isIntegerTy() ||
+ !TLI.isOperationLegalOrCustom(ISD::BITREVERSE,
+ TLI.getValueType(DL, I.getType(), true)))
+ return false;
+
+ SmallVector<Instruction*, 4> Insts;
+ if (!recognizeBitReverseOrBSwapIdiom(&I, false, true, Insts))
+ return false;
+ Instruction *LastInst = Insts.back();
+ I.replaceAllUsesWith(LastInst);
+ RecursivelyDeleteTriviallyDeadInstructions(&I);
+ return true;
+}
+
// In this pass we look for GEP and cast instructions that are used
// across basic blocks and rewrite them to improve basic-block-at-a-time
// selection.
@@ -5226,6 +5244,17 @@ bool CodeGenPrepare::optimizeBlock(BasicBlock &BB, bool& ModifiedDT) {
}
MadeChange |= dupRetToEnableTailCallOpts(&BB);
+ bool MadeBitReverse = true;
+ while (TLI && MadeBitReverse) {
+ MadeBitReverse = false;
+ for (auto &I : reverse(BB)) {
+ if (makeBitReverse(I, *DL, *TLI)) {
+ MadeBitReverse = MadeChange = true;
+ break;
+ }
+ }
+ }
+
return MadeChange;
}
OpenPOWER on IntegriCloud