[PATCH] Expand SimplifyCFG to convert certain simple switches to selects
Philip Reames
listmail at philipreames.com
Mon Jun 23 11:13:49 PDT 2014
I really like the overall direction of this patch, but it could use a bit of cleanup for readability.
You might also be able to generalize some of the transform:
- single unique value + default
- default probably dead without transform
================
Comment at: lib/Transforms/Utils/SimplifyCFG.cpp:3686
@@ +3685,3 @@
+ Constant *&DefaultResult) {
+ for (auto I = SI->case_begin(), E = SI->case_end(); I != E; ++I) {
+ ConstantInt *CaseVal = I.getCaseValue();
----------------
range loop?
================
Comment at: lib/Transforms/Utils/SimplifyCFG.cpp:3700
@@ +3699,3 @@
+ // intermediate unconditional block to the common destination.
+ if (CaseSuccessor != CommonDest &&
+ !(BI && BI->isUnconditional() && BI->getSuccessor(0) == CommonDest))
----------------
split the two early exit cases? might improve readability, particularly if the CaseSuccessor != CommonDest check is above BI.
================
Comment at: lib/Transforms/Utils/SimplifyCFG.cpp:3713
@@ +3712,3 @@
+ return false;
+ if (ResultFound == UniqueResults.end()) {
+ UniqueResults[Result.second].push_back(CaseVal);
----------------
You might restructure this to put ResultFound closer to it's use and separate the two if/else clauses.
================
Comment at: lib/Transforms/Utils/SimplifyCFG.cpp:3725
@@ +3724,3 @@
+ DL);
+ // No default case makes us assume that default is not possible.
+ DefaultResult =
----------------
It looks like you might end up with PHI unset if you had a switch with only a default case. Could such a switch reach here?
================
Comment at: lib/Transforms/Utils/SimplifyCFG.cpp:3766
@@ +3765,3 @@
+// select.
+static Value *
+ConvertTwoCaseSwitch(const SmallVectorImpl<ConstantInt *> &FirstGroupCases,
----------------
It looks like this code is actually handling two cases + default. Update the comment?
Also, is it always profitable to replace one switch with two selects? I would guess not, but will defer to actual measurement.
================
Comment at: lib/Transforms/Utils/SimplifyCFG.cpp:3814
@@ +3813,3 @@
+// transform a switch with cases arranged into two ordered not overlapping
+// groups into a value select
+static Value *
----------------
Could you add examples to your function comments? It would make them a bit more obvious.
================
Comment at: lib/Transforms/Utils/SimplifyCFG.cpp:3902
@@ +3901,3 @@
+ // Selects choose between two values only.
+ if (UniqueResults.size() != 2)
+ return false;
----------------
Since you're handling defaults, wouldn't it also make sense to handle one unique result and a default? i.e.
switch(i) {
case 4,5,6: return 5;
default: return 0;
}
================
Comment at: lib/Transforms/Utils/SimplifyCFG.cpp:3955
@@ +3954,3 @@
+ (FirstPossibleHits + SecondPossibleHits)) != 0);
+ DefaultCanTrigger &= DefaultResult != nullptr;
+
----------------
It seems like proving the switch default is dead is a useful optimization even if we can make no other changes. Should this be separated and generalized?
================
Comment at: lib/Transforms/Utils/SimplifyCFG.cpp:3964
@@ +3963,3 @@
+ // try finding a bit pattern that covers the cases and test on that
+ if (SelectValue == nullptr) {
+ SelectValue = ConvertBitPatternSwitch(
----------------
The general convention used is an early return when a change is made, not a signal value (nullptr here) when a change isn't made. In this particular example, I believe using that pattern would make the code much easier to follow.
================
Comment at: lib/Transforms/Utils/SimplifyCFG.cpp:3974
@@ +3973,3 @@
+
+ PHI->addIncoming(SelectValue, SI->getParent());
+
----------------
Everything from here on could easily be a helper function.
http://reviews.llvm.org/D4219
More information about the llvm-commits
mailing list