This is an archive of the discontinued LLVM Phabricator instance.

[ScopInfo] Do not use LLVM names to identify statements
ClosedPublic

Authored by grosser on May 3 2017, 3:15 AM.

Details

Summary

LLVM-IR names are commonly available in debug builds, but often not in release
builds. Hence, using LLVM-IR names to identify statements or memory reference
results makes the behavior of Polly depend on the compile mode. This is
undesirable. Hence, we now just number the statements instead of using LLVM-IR
names to identify them (this issue has previously been brought up by Zino
Benaissa).

However, as LLVM-IR names help in making test cases more readable, we add an
option '-polly-use-llvmir-names' to still use LLVM-IR names. This flag
is by default set in the polly tests to make test cases more readable.

This change reduces the time in ScopInfo from 32 seconds to 2 seconds for the
following test case provided by Eli Friedman <efriedma@codeaurora.org> (already
used in one of the previous commits):

struct X { int x; };
void a();
#define SIG (int x, X **y, X **z)
typedef void (*fn)SIG;
#define FN { for (int i = 0; i < x; ++i) { (*y)[i].x += (*z)[i].x; } a(); }
#define FN5 FN FN FN FN FN
#define FN25 FN5 FN5 FN5 FN5
#define FN125 FN25 FN25 FN25 FN25 FN25
#define FN250 FN125 FN125
#define FN1250 FN250 FN250 FN250 FN250 FN250
void x SIG { FN1250 }

For a larger benchmark I have on-hand (10000 loops), this reduces the time for
running -polly-scops from 5 minutes to 4 minutes, a reduction by 20%.

The reason for this large speedup is that our previous use of printAsOperand
had a quadratic cost, as for each printed and unnamed operand the full function
was scanned to find the instruction number that identifies the operand.

We do not need to adjust the way memory reference ids are constructured, as
they do not use LLVM values.

Event Timeline

grosser created this revision.May 3 2017, 3:15 AM
efriedma edited edge metadata.May 3 2017, 11:22 AM

This looks very similar to a change we made internally (down to the name; we call it -polly-use-llvm-names). We originally did it because we were having trouble with differences in generated code between Release and Release+Asserts builds, but the performance improvement is a nice side-effect.

Should polly-use-llvmir-names control the behavior of Scop::createParameterId?

grosser updated this revision to Diff 97714.May 3 2017, 12:56 PM
  • Rename option to -polly-use-llvm-names, this is sounds better and even matches

the qualcomm internal option.

  • Also guard createParameterId. While this is not necessary to obtain the speedup we see, it is needed to make Polly deterministic independently if instructions are named or not.
grosser updated this revision to Diff 97715.May 3 2017, 12:57 PM

Drop redundant "use namespace llvm" declaration

efriedma accepted this revision.May 3 2017, 1:16 PM

LGTM.

This revision is now accepted and ready to land.May 3 2017, 1:16 PM
This revision was automatically updated to reflect the committed changes.
Meinersbur edited edge metadata.May 4 2017, 3:55 AM

Some post-commit remarks.

polly/trunk/include/polly/ScopInfo.h
1714 ↗(On Diff #97721)

long is 32 bits on 32 bit system and any Windows system. If you really think 32 bits are not enough, could you consider using long long or int64_t?

2634 ↗(On Diff #97721)

This method has a getter-function name, but has side-effects.

Did you consider passing the ArrayIdx to ScopArrayInfo's ctor instead?

polly/trunk/lib/Support/GICHelper.cpp
218 ↗(On Diff #97721)

Isn't making it also dependent on Val->hasName() a breaking/unrelated change? Before, the number was derived by LLVM taking all Value's into account. Now the id is derived from the order the unnamed value is encountered by Polly.

I wouldn't consider it a compile-time improvement either because LLVM still looks for duplicate name if it has a name. If UseInstructionNames is enabled, I'd expect names to be derived consistently by LLVM. It is also not consistent with the other overload and the function's description, which says it's only dependent on UseInstructionNames.

219 ↗(On Diff #97721)

ValStr = std::string("_") + Val->getName() should suffice.