Skip to content

Reducing switch range on powers of two #70756

Closed
@DKay7

Description

@DKay7

I recently found FIXME:

// FIXME: It's possible that optimizing a switch on powers of two might also
// be beneficial - flag values are often powers of two and we could use a CLZ
// as the key function.

I decided to implement it. My Idea was, as described in FIXME, to check if switch contains only powers of two, and if so, to replace each key with countl_zero(key). When I'm almost done, I ran into a problem that I also need to change the switch condition to countl_zero(condition). I tried to find some simple and fast algorithm to count leading zeros in runtime, but all algorithms are too slow or too complex. Should I try to implement something complicated at all, or is this optimization not worth it?

My current approach looks like that:

  SmallVector<int64_t,4> Values;
  for (const auto &Case : SI->cases())
    Values.push_back(Case.getCaseValue()->getValue().getSExtValue());
  
  if (!IsSwitchOfPowersOfTwo(Values))
    return false;


  Builder.SetInsertPoint(SI);
  auto *Ty = cast<IntegerType>(SI->getCondition()->getType());
  
  SI->replaceUsesOfWith(SI->getCondition(), /* TODO: count leading zeros of SI->getCondition() */);
  
  for (auto Case : SI->cases()) {
    auto OrigValue = Case.getCaseValue()->getValue();
    Case.setValue(
        cast<ConstantInt>(ConstantInt::get(Ty, OrigValue.countl_zero())));
  }

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions