This is an archive of the discontinued LLVM Phabricator instance.

[InlineCost] add visitSelectInst()
ClosedPublic

Authored by haicheng on Aug 27 2017, 11:48 AM.

Details

Summary

This patch adds visitSelectInst() to find free Select IRs and continue the propagation of SimplifiedValues, ConstantOffsetPtrs, and SROAArgValues.

We don't need all operands of Select IR to be constants to fold it, so I don't use the generic CallAnalyzer::simplifyInstruction().

The impact on SPEC20xx is below

BenchmarkCode Size (%)Perf (%)
(+ is bigger)(+ is faster)
spec2000/gcc0.011.08
spec2000/mesa0.042.2
spec2000/twolf-0.15-0.01
spec2006/gcc0.02-0.19
spec2006/h264ref0.330.18
spec2017/blender0.010.5
spec2017/gcc0.010.09
spec2017/imagick0.020.01
spec2017/parest0-0.05
spec2017/perlbench0.10.56

Diff Detail

Repository
rL LLVM

Event Timeline

haicheng created this revision.Aug 27 2017, 11:48 AM
mcrosier edited edge metadata.Aug 28 2017, 8:54 AM

Overall, the logic of the patch is in good shape. However, I'd suggest some minor refactoring to delineate the select of constants/values vs. GEPs for SROA.

Maybe something like this:

bool CallAnalyzer::visitSelectInst(SelectInst &SI) {
  Value *TrueVal = SI.getTrueValue();
  Value *FalseVal = SI.getFalseValue();

  Constant *TrueC = isa<Constant>(TrueVal) ? cast<Constant>(TrueVal)
                                           : SimplifiedValues.lookup(TrueVal);
  Constant *FalseC = isa<Constant>(FalseVal)
                         ? cast<Constant>(FalseVal)
                         : SimplifiedValues.lookup(FalseVal);
  // Select C, X, X => X
  if (TrueC && FalseC && TrueC == FalseC) {
    SimplifiedValues[&SI] = TrueC;
    return true;
  }

  Type *ValTy = FalseVal->getType();
  assert(TrueVal->getType() == FalseVal->getType() &&
         "Expected matching types.");

  Constant *CondC =
      dyn_cast_or_null<Constant>(SimplifiedValues.lookup(SI.getCondition()));
  // Select condition is a constant.
  if (CondC && !ValTy->isPointerTy()) {
    // Select True, X, Y => X
    if (CondC->isAllOnesValue() && TrueC)
      SimplifiedValues[&SI] = TrueC;
    // Select False, X, Y => Y
    if (CondC->isNullValue() && FalseC)
      SimplifiedValues[&SI] = FalseC;
    // If all operands are constants.  ConstantExpr::getSelect() can handle
    // rest cases such as select vectors.
    if (TrueC && FalseC)
      if (Constant *C = ConstantExpr::getSelect(CondC, TrueC, FalseC))
        SimplifiedValues[&SI] = C;
    return true;
  }

  // Logic for SROA follows
  // Select C, X, X => X
  // Select True, X, Y => X
  // Select False, X, Y => Y

  return Base::visitSelectInst(SI);
}

IMHO this is a little easier to read.

haicheng updated this revision to Diff 113429.Aug 31 2017, 10:11 AM

Move code around as suggested by Chad. Thank you.

Kindly PIng

eastig added a subscriber: eastig.Sep 7 2017, 12:34 PM
mcrosier added inline comments.Sep 13 2017, 9:53 AM
lib/Analysis/InlineCost.cpp
1190 ↗(On Diff #113429)

Not sure it matters a great deal, but this could also be written as

if ((TrueC || FalseC) && TrueC == FalseC) {

Feel free to take it or leave it; either way is probably fine.

1211 ↗(On Diff #113429)

can handle the rest of the cases, such as select vectors.

1220 ↗(On Diff #113429)

toi -> to

eraman added inline comments.Sep 13 2017, 3:51 PM
lib/Analysis/InlineCost.cpp
1182 ↗(On Diff #113429)

I added simplifyInstruction to handle instruction simplification with constant values. Now, it handles cases only when all the operands are constants - either as such or after looking up SimplifiedValues. It can be extended to handle cases like this where you don't need all operands to be constants. May be add a bool to indicate whether it should call the Callable even if all operands are not constants and use that here?

haicheng updated this revision to Diff 115570.Sep 17 2017, 5:36 AM
haicheng marked 3 inline comments as done.

Extend simplifyInstruction() to handle the cases that not all operands are constants. Use SimplifySelectInst() to process Select.

Thank you.

Haicheng

eraman added inline comments.Sep 19 2017, 5:47 PM
lib/Analysis/InlineCost.cpp
496 ↗(On Diff #115570)

Sorry, I should have thought through this carefully. My bad. I feel this version is worse than before. Most callers of simplifyInstruction pass a callable that takes a vector of Value * and implicitly treats it as a vector of Constant *. Feel free to go back the the previous version or come up with a better way to refactor simplifyInstruction. My main motivation for the refactoring was to keep accesses to SimplifiedValues in one location, so that we can get data on how often does inlining actually simplifies a value to a constant.

chandlerc requested changes to this revision.Sep 19 2017, 6:15 PM

Just wanted to say thanks so much for working on this -- its a huge improvement to the inline cost.

lib/Analysis/InlineCost.cpp
496 ↗(On Diff #115570)

FWIW, I agree. I looked at both versions, and I think the custom select handling is better. It's hard to tell ahead of time, so still, thanks for exploring whether this helps.

1201 ↗(On Diff #113429)

No need to separately test for true and false once you know the condition is a constant. Just check isNullValue(). It's either false, or true. =]

1212–1217 ↗(On Diff #113429)

I feel like we should handle this above when handling TrueC == FalseC.

1222–1249 ↗(On Diff #113429)

I think this code will be substantially simpler if you refactor it in the following way.

First, check if the condition is a constant. If *not* a constant, then handle the only cases we can handle in that world: equal (or constant expr-able) inputs, or matching SROA args like here. Then return.

Rest of the function only handling when it *is* a constant. Then assign the input the constant will select to a variable, and only do all the checks on that one variable rather on both true and false variants.

This revision now requires changes to proceed.Sep 19 2017, 6:15 PM

Thank you, Chandler. I will update the patch shortly.

lib/Analysis/InlineCost.cpp
1201 ↗(On Diff #113429)

The vector constant condition can be <i1 true, i1 false>. It is neither AllOnesValue or NullValue.

chandlerc added inline comments.Sep 21 2017, 10:15 PM
lib/Analysis/InlineCost.cpp
1201 ↗(On Diff #113429)

Ah, I see.

But if you have a constant condition, even if a vector with a mixture of true and false elements, you can fully simulate the select (and we should). The test should be "is it a constant". Once we know that it is, we should be able to get at each element and test whether that element is a null value or not. And then the scalar case will just be the same as a 1-element vector.

haicheng updated this revision to Diff 116367.Sep 22 2017, 10:01 AM
haicheng edited edge metadata.

Back to the customized implementation, reorganized the code, rewrote the test cases.

Please take a look. Thank you.

chandlerc requested changes to this revision.Sep 22 2017, 11:16 AM

Mostly minor suggestions below...

lib/Analysis/InlineCost.cpp
1186–1190 ↗(On Diff #116367)

I'd still use dyn_cast here:

Constant *TrueC = dyn_cast<Constant>(TrueVal);
if (!TrueC)
  TrueC = SimplifiedValues.lookup(TrueVal);
1196 ↗(On Diff #116367)

I'd simplify this as: TrueC == FalseC && TrueC.

1230 ↗(On Diff #116367)

auto?

1238–1239 ↗(On Diff #116367)

I think just dyn_cast<Constant>(SelectedV) is easier to read and no more expensive.

This revision now requires changes to proceed.Sep 22 2017, 11:16 AM
haicheng updated this revision to Diff 116451.Sep 22 2017, 6:07 PM
haicheng edited edge metadata.
haicheng marked 5 inline comments as done.

Address Chandler's comments. Please take a look. Thank you.

This is looking pretty good. Some nit-picky improvements below. I'd love for Easwaran to get another chance to look at this too though...

lib/Analysis/InlineCost.cpp
1202 ↗(On Diff #116451)

Prefer early exit here, and below:

if (!CheckSROA)
  return Base::visitSelectInst(SI);
1207–1208 ↗(On Diff #116451)

Similar to the above, this can be:

if (TrueBaseAndOffset == FalseBaseAndOffset && TrueBaseAndOffset.first)
1245 ↗(On Diff #116451)

Early return here as well.

haicheng updated this revision to Diff 116698.Sep 26 2017, 1:08 PM
haicheng marked 3 inline comments as done.

Address Chandler's comments. Please take a look. Thank you.

chandlerc accepted this revision.Sep 26 2017, 11:24 PM

(Marking as accepted now that Easwaran has had a chance to look as well)

This revision is now accepted and ready to land.Sep 26 2017, 11:24 PM
This revision was automatically updated to reflect the committed changes.