[llvm-commits] [llvm] r164682 - /llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
Duncan Sands
baldrick at free.fr
Wed Sep 26 03:23:44 PDT 2012
Hi Hans,
> --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original)
> +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Wed Sep 26 04:34:53 2012
> @@ -3240,61 +3240,127 @@
> return true;
> }
>
> -/// BuildLookupTable - Build a lookup table with the contents of Results, using
> -/// DefaultResult to fill the holes in the table. If the table ends up
> -/// containing the same result in each element, set *SingleResult to that value
> -/// and return NULL.
> -static GlobalVariable *BuildLookupTable(Module &M,
> - uint64_t TableSize,
> - ConstantInt *Offset,
> - const SmallVector<std::pair<ConstantInt*, Constant*>, 4>& Results,
> - Constant *DefaultResult,
> - Constant **SingleResult) {
> - assert(Results.size() && "Need values to build lookup table");
> - assert(TableSize >= Results.size() && "Table needs to hold all values");
> +namespace {
> + /// SwitchLookupTable - This class represents a lookup table that can be used
> + /// to replace a switch.
> + class SwitchLookupTable {
> + public:
> + /// SwitchLookupTable - Create a lookup table to use as a switch replacement
> + /// with the contents of Values, using DefaultValue to fill any holes in the
> + /// table.
> + SwitchLookupTable(Module &M,
> + uint64_t TableSize,
> + ConstantInt *Offset,
> + const SmallVector<std::pair<ConstantInt*, Constant*>, 4>& Values,
> + Constant *DefaultValue);
> +
> + /// BuildLookup - Build instructions with Builder to retrieve the value at
> + /// the position given by Index in the lookup table.
> + Value *BuildLookup(Value *Index, IRBuilder<> &Builder);
> +
> + private:
> + // Depending on the contents of the table, it can be represented in
> + // different ways.
> + enum {
> + // For tables where each element contains the same value, we just have to
> + // store that single value and return it for each lookup.
> + SingleValueKind,
> +
> + // The table is stored as an array of values. Values are retrieved by load
> + // instructions from the table.
> + ArrayKind
> + } Kind;
> +
> + // For SingleValueKind, this is the single value.
> + Constant *SingleValue;
> +
> + // For ArrayKind, this is the array.
> + GlobalVariable *Array;
> + };
> +}
> +
> +SwitchLookupTable::SwitchLookupTable(Module &M,
> + uint64_t TableSize,
> + ConstantInt *Offset,
> + const SmallVector<std::pair<ConstantInt*, Constant*>, 4>& Values,
> + Constant *DefaultValue) {
> + assert(Values.size() && "Can't build lookup table without values.");
> + assert(TableSize >= Values.size() && "Can't fit values in table.");
traditionally assert messages finish with an exclamation mark (!) rather than a
full stop (.).
...
> +/// ShouldBuildLookupTable - Determine whether a lookup table should be built
> +/// for this switch, based on the number of caes, size of the table and the
> +/// types of the results.
> +static bool ShouldBuildLookupTable(SwitchInst *SI,
> + uint64_t TableSize) {
> + // The table density should be at least 40%. This is the same criterion as for
> + // jump tables, see SelectionDAGBuilder::handleJTSwitchCase.
> + // FIXME: Find the best cut-off.
> + if (SI->getNumCases() * 10 >= TableSize * 4)
This should protect itself against overflow. For example you can return false
if SI-getNumCases() >= TableSize, and if TableSize >= (~0ULL) / 10. Then you
know that neither multiplication overflows. Probably there is an even simpler
way.
> + return true;
> +
> + return false;
> }
>
> /// SwitchToLookupTable - If the switch is only used to initialize one or more
...
> @@ -3370,33 +3436,16 @@
> }
>
> APInt RangeSpread = MaxCaseVal->getValue() - MinCaseVal->getValue();
> - // The table density should be at lest 40%. This is the same criterion as for
> - // jump tables, see SelectionDAGBuilder::handleJTSwitchCase.
> - // FIXME: Find the best cut-off.
> - // Be careful to avoid overlow in the density computation.
> + // Be careful to avoid overflow when TableSize is used in
> + // ShouldBuildLookupTable.
These kind of mutual dependencies (adjusting things here so the routine called
a bit below doesn't overflow) are bad, I think ShouldBuildLookupTable should be
fixed to just always return a sensible result.
Ciao, Duncan.
More information about the llvm-commits
mailing list