[llvm] [SimplifyCFG] Simplify switch instruction that has duplicate arms (PR #114262)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 14 08:28:24 PST 2024
================
@@ -7436,6 +7437,185 @@ static bool simplifySwitchOfCmpIntrinsic(SwitchInst *SI, IRBuilderBase &Builder,
return true;
}
+/// Checking whether two cases of SI are equal depends on the contents of the
+/// BasicBlock and the incoming values of their successor PHINodes.
+/// PHINode::getIncomingValueForBlock is O(|Preds|), so we'd like to avoid
+/// calling this function on each BasicBlock every time isEqual is called,
+/// especially since the same BasicBlock may be passed as an argument multiple
+/// times. To do this, we can precompute a map of PHINode -> Pred BasicBlock ->
+/// IncomingValue and add it in the Wrapper so isEqual can do O(1) checking
+/// of the incoming values.
+struct SwitchSuccWrapper {
+ // Keep so we can use SwitchInst::setSuccessor to do the replacement. It won't
+ // be important to equality though.
+ unsigned SuccNum;
+ BasicBlock *Dest;
+ DenseMap<PHINode *, DenseMap<BasicBlock *, Value *>> *PhiPredIVs;
+};
+
+namespace llvm {
+template <> struct DenseMapInfo<const SwitchSuccWrapper *> {
+ static const SwitchSuccWrapper *getEmptyKey() {
+ return static_cast<SwitchSuccWrapper *>(
+ DenseMapInfo<void *>::getEmptyKey());
+ }
+ static const SwitchSuccWrapper *getTombstoneKey() {
+ return static_cast<SwitchSuccWrapper *>(
+ DenseMapInfo<void *>::getTombstoneKey());
+ }
+ static unsigned getHashValue(const SwitchSuccWrapper *SSW) {
+ BasicBlock *Succ = SSW->Dest;
+ BranchInst *BI = cast<BranchInst>(Succ->getTerminator());
+ assert(BI->isUnconditional() &&
+ "Only supporting unconditional branches for now");
+ assert(BI->getNumSuccessors() == 1 &&
+ "Expected unconditional branches to have one successor");
+ assert(Succ->size() == 1 && "Expected just a single branch in the BB");
+
+ // Since we assume the BB is just a single BranchInst with a single
+ // succsessor, we hash as the BB and the incoming Values of its successor
+ // PHIs. Initially, we tried to just use the successor BB as the hash, but
+ // this had poor performance. We find that the extra computation of getting
+ // the incoming PHI values here leads to better performance on overall Set
+ // performance. We also tried to build a map from BB -> Succs.IncomingValues
----------------
nikic wrote:
```suggestion
// PHIs. Initially, we tried to just use the successor BB as the hash, but
// including the incoming PHI values leads to better performance.
// We also tried to build a map from BB -> Succs.IncomingValues
```
There was a lot of performance in here.
https://github.com/llvm/llvm-project/pull/114262
More information about the llvm-commits
mailing list