llvmdev 2016 - loop passes - adding new features while

53
Loop Passes Adding New Features While Reducing Technical Debt Michael Zolotukhin

Upload: others

Post on 26-May-2022

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: LLVMDev 2016 - Loop Passes - Adding New Features While

Loop Passes

Adding New Features While Reducing Technical Debt

Michael Zolotukhin

Page 2: LLVMDev 2016 - Loop Passes - Adding New Features While

Adding New Features

• Implementation

• Testing

• Review

• Maintenance

• Paying off technical debt

Page 3: LLVMDev 2016 - Loop Passes - Adding New Features While

Technical Debt• Bugs

Oops! Didn’t see it!

• Non-optimal solutions

Works for now! It’s just a temporary solution.

• Unfinished solutions

That’s enough for my case! We’ll finish it… one day.

Page 4: LLVMDev 2016 - Loop Passes - Adding New Features While

Loop Unrolling New Heuristics

• Analyze loop body

• Predict potential outcomes of other optimizations if we unroll

LLVMDev 2015: “Advances in Loop Analysis Frameworks and Optimizations”

Page 5: LLVMDev 2016 - Loop Passes - Adding New Features While

• Performance improves

• Code size increases

• Compile time increases

Loop Unrolling Effects

Page 6: LLVMDev 2016 - Loop Passes - Adding New Features While

Compile Time

1

1.25

1.5

3.6 3.7 3.8 3.9

O0 O3 Os

Page 7: LLVMDev 2016 - Loop Passes - Adding New Features While

• Check compile time impact

• Tune optimization thresholds

• Look for potential problems

Loop Unrolling Stress Testing

Page 8: LLVMDev 2016 - Loop Passes - Adding New Features While

MPM.add(createLoopRotatePass());

MPM.add(createCFGSimplificationPass());

MPM.add(createIndVarSimplifyPass());

MPM.add(createSimpleLoopUnrollPass());

Pass Structure

Page 9: LLVMDev 2016 - Loop Passes - Adding New Features While

Prepare(F);for (Loop *L : F) { Rotate(L); SimplifyCFG(); IndVars(L); Unroll(L);}

Pass Structure

Page 10: LLVMDev 2016 - Loop Passes - Adding New Features While

Prepare(F);for (Loop *L : F) { Rotate(L);} SimplifyCFG();Prepare(F);for (Loop *L : F) { IndVars(L);} Prepare(F);for (Loop *L : F) { Unroll(L);}

Pass Structure

Page 11: LLVMDev 2016 - Loop Passes - Adding New Features While

Prepare(F);for (Loop *L : F) { Rotate(L);} SimplifyCFG();Prepare(F);for (Loop *L : F) { IndVars(L);} Prepare(F);for (Loop *L : F) { Unroll(L);}

Pass Structure

Page 12: LLVMDev 2016 - Loop Passes - Adding New Features While

Prepare(F);for (Loop *L : F) { Rotate(L);} SimplifyCFG();Prepare(F);for (Loop *L : F) { IndVars(L);} Prepare(F);for (Loop *L : F) { Unroll(L);}

Pass Structure

Page 13: LLVMDev 2016 - Loop Passes - Adding New Features While

Prepare(F);for (Loop *L : F) { Rotate(L);} SimplifyCFG();Prepare(F);for (Loop *L : F) { IndVars(L); Unroll(L);}

Pass Structure

Page 14: LLVMDev 2016 - Loop Passes - Adding New Features While

Prepare(F);for (Loop *L : F) { Rotate(L);} SimplifyCFG();Prepare(F);for (Loop *L : F) { IndVars(L); Unroll(L);}

Pass Structure

Page 15: LLVMDev 2016 - Loop Passes - Adding New Features While

Prepare(F);for (Loop *L : F) { Rotate(L); LoopSimplifyCFG(L); IndVars(L); Unroll(L);}

Pass Structure

Page 16: LLVMDev 2016 - Loop Passes - Adding New Features While

Prepare(F);for (Loop *L : F) { Rotate(L); LoopSimplifyCFG(L); IndVars(L); Unroll(L);}

Pass Structure

Page 17: LLVMDev 2016 - Loop Passes - Adding New Features While

Prepare(F);for (Loop *L : F) { Rotate(L); LoopSimplifyCFG(L); IndVars(L); Unroll(L); }

Pass StructureBuildDT(F);BuildLCSSA(F);SimplifyLoops(F);

Page 18: LLVMDev 2016 - Loop Passes - Adding New Features While

Prepare(F);for (Loop *L : F) { Rotate(L); SimplifyCFG(); IndVars(L); Unroll(L); }

Pass Structure

Transform(L);RebuildDT(F);

Page 19: LLVMDev 2016 - Loop Passes - Adding New Features While

Updating DomTreeA

B C

D E

F

Page 20: LLVMDev 2016 - Loop Passes - Adding New Features While

A

B C

D E

F

A

B C

D E

F

Updating DomTree

Page 21: LLVMDev 2016 - Loop Passes - Adding New Features While

A

B C

D

A*

B* C*

D* E

F

A

B C

D

A*

B* C*

D* E

F

Updating DomTree

Page 22: LLVMDev 2016 - Loop Passes - Adding New Features While

A

B C

D

A*

B* C*

D* E

F

A

B C

D

A*

B* C*

D* E

F

Updating DomTree

Page 23: LLVMDev 2016 - Loop Passes - Adding New Features While

A

B C

D

A*

B* C*

D* E

F

A

B C

D

A*

B* C*

D* E

F

Updating DomTree

Page 24: LLVMDev 2016 - Loop Passes - Adding New Features While

A

B C

D

A*

B* C*

D* E

F

A

B C

D

A*

B* C*

D* E

F

Updating DomTree

Page 25: LLVMDev 2016 - Loop Passes - Adding New Features While

Prepare(F);for (Loop *L : F) { Rotate(L); SimplifyCFG(); IndVars(L); Unroll(L); }

Pass Structure

Transform(L);RebuildDT(F);

Page 26: LLVMDev 2016 - Loop Passes - Adding New Features While

Prepare(F);for (Loop *L : F) { Rotate(L); SimplifyCFG(); IndVars(L); Unroll(L); }

Pass Structure

Transform(L);UpdateDT(L);

Page 27: LLVMDev 2016 - Loop Passes - Adding New Features While

Prepare(F);for (Loop *L : F) { Rotate(L); SimplifyCFG(); IndVars(L); Unroll(L); }

Pass Structure

Transform(L);UpdateDT(L);RebuildLCSSA(F);

Page 28: LLVMDev 2016 - Loop Passes - Adding New Features While

Loop Closed SSA

• All definitions are used only inside the same loop or in phis in exit blocks

• Predecessors of all exit blocks belong to this loop

Page 29: LLVMDev 2016 - Loop Passes - Adding New Features While

Updating LCSSA

c = b * 4;} while (outer);

b = a + 1; } while (inner);

do {

do { a = …;

Page 30: LLVMDev 2016 - Loop Passes - Adding New Features While

%a = ...

%c = %b * 4

%b = %a + 1

Updating LCSSA

c = b * 4;} while (outer);

b = a + 1; } while (inner);

do {

do { a = …;

Page 31: LLVMDev 2016 - Loop Passes - Adding New Features While

%a = ...

%c = %b * 4

%b = %a + 1

Updating LCSSA

c = b * 4;} while (outer);

b = a + 1; } while (inner);

do {

do { a = …;

Page 32: LLVMDev 2016 - Loop Passes - Adding New Features While

%a = ...

%c = %b * 4

%b = %a + 1

Updating LCSSA

c = b * 4;} while (outer);

b = a + 1; } while (inner);

do {

do { a = …;

Page 33: LLVMDev 2016 - Loop Passes - Adding New Features While

%a = ...

%c = %b * 4

%b = %a + 1

Updating LCSSA

c = b * 4;} while (outer);

b = a + 1; } while (inner);

do {

do { a = …;

Page 34: LLVMDev 2016 - Loop Passes - Adding New Features While

%a = ...

%x = phi %b%c = %x * 4

%b = %a + 1

Updating LCSSA

c = b * 4;} while (outer);

b = a + 1; } while (inner);

do {

do { a = …;

Page 35: LLVMDev 2016 - Loop Passes - Adding New Features While

%a = ...

%x = phi %b%c = %x * 4

%b = %a + 1

Updating LCSSA

c = b * 4;} while (outer);

b = a + 1;

do { a = …;

Page 36: LLVMDev 2016 - Loop Passes - Adding New Features While

Updating LCSSAwhile (outer) { a = …;

while (inner) {

b = a + 1; if (exit) return; }

}

Page 37: LLVMDev 2016 - Loop Passes - Adding New Features While

Updating LCSSAwhile (outer) { a = …;

while (inner) {

b = a + 1; if (exit) return; }

}

%a = ...

%b = %a + 1

Page 38: LLVMDev 2016 - Loop Passes - Adding New Features While

Updating LCSSAwhile (outer) { a = …;

while (inner) {

b = a + 1; if (exit) return; }

}

%a = ...

%b = %a + 1

Page 39: LLVMDev 2016 - Loop Passes - Adding New Features While

Updating LCSSAwhile (outer) { a = …;

while (inner) {

b = a + 1; if (exit) return; }

}

%a = ...

%b = %a + 1

Page 40: LLVMDev 2016 - Loop Passes - Adding New Features While

Updating LCSSAwhile (outer) { a = …;

while (inner) {

b = a + 1; return; }

}

%b = %a + 1

%a = ...

Page 41: LLVMDev 2016 - Loop Passes - Adding New Features While

Updating LCSSAwhile (outer) { a = …;

if (inner) {

b = a + 1; return; }

}

%b = %a + 1

%a = ...

Page 42: LLVMDev 2016 - Loop Passes - Adding New Features While

Updating LCSSAwhile (outer) { a = …;

if (inner) {

b = a + 1; return; }

}

%b = %a + 1

%a = ...

Page 43: LLVMDev 2016 - Loop Passes - Adding New Features While

Prepare(F);for (Loop *L : F) { Rotate(L); LoopSimplifyCFG(L); IndVars(L); Unroll(L); }

Pass Structure

Transform(L);UpdateDT(L);RebuildLCSSA(F);

Page 44: LLVMDev 2016 - Loop Passes - Adding New Features While

Prepare(F);for (Loop *L : F) { Rotate(L); LoopSimplifyCFG(L); IndVars(L); Unroll(L); }

Pass Structure

Transform(L);UpdateDT(L);if (ReallyReallyNeedToRebuild) RebuildLCSSA(F);

Page 45: LLVMDev 2016 - Loop Passes - Adding New Features While

Prepare(F);for (Loop *L : F) { Rotate(L); LoopSimplifyCFG(L); IndVars(L); Unroll(L); }

Pass Structure

Transform(L);UpdateDT(L);if (ReallyReallyNeedToRebuild) RebuildLCSSA(F);VerifyLCSSA(F);

Page 46: LLVMDev 2016 - Loop Passes - Adding New Features While

Prepare(F);for (Loop *L : F) { Rotate(L); LoopSimplifyCFG(L); IndVars(L); Unroll(L); }

Pass Structure

Transform(L);UpdateDT(L);if (ReallyReallyNeedToRebuild) RebuildLCSSA(F);VerifyLCSSA(F); // FAIL!

Page 47: LLVMDev 2016 - Loop Passes - Adding New Features While

Prepare(F);for (Loop *L : F) { Rotate(L); LoopSimplifyCFG(L); IndVars(L); Unroll(L); }

Pass Structure

VerifyLCSSA(F); // FAIL!Transform(L);UpdateDT(L);if (ReallyReallyNeedToRebuild) RebuildLCSSA(F);VerifyLCSSA(F); // FAIL!

Page 48: LLVMDev 2016 - Loop Passes - Adding New Features While

Prepare(F);for (Loop *L : F) { Rotate(L); VerifyLCSSA(F); LoopSimplifyCFG(L); VerifyLCSSA(F); IndVars(L); VerifyLCSSA(F); Unroll(L); VerifyLCSSA(F);}

Pass Structure

Page 49: LLVMDev 2016 - Loop Passes - Adding New Features While

Bugs DetectedBug 25538 - clang crashes on valid code at -O2 on x86_64-linux-gnu

Bug 25578 - IndVarSimplify breaks LCSSA form, while saying it's preserved

Bug 26682 - crash on x86_64-linux-gnu at -O2 and above in both 32-bit and 64-bit modes (Assertion `L->isRecursivelyLCSSAForm(*DT) && "Indvars did not preserve LCSSA!"' failed)

Bug 26688 - Assert in LoopUnroll.cpp: Loops should be in LCSSA form after loop-unroll.

Bug 27157 - opt -O3 crashes with debug-only=loop-unroll

Bug 27945 - Compiler crash in "Induction Variable Simplification" for “-fno-exceptions"

Bug 28048 - crash at -Os, -O2 and -O3 in 32-bit and 64-bit mode on x86_64-linux-gnu (`L->isRecursivelyLCSSAForm(*DT) && "LCSSA required to run indvars!”')

Bug 28272 - LoopSimplify does not preserve LCSSA when separating nested loops.

Bug 28424 - Assertion `InLCSSA && "Requested to preserve LCSSA, but it's already broken."' failed.

...

Page 50: LLVMDev 2016 - Loop Passes - Adding New Features While

Prepare(F);for (Loop *L : F) { Rotate(L); VerifyLoopAnalyses(F); LoopSimplifyCFG(L); VerifyLoopAnalyses(F); IndVars(L); VerifyLoopAnalyses(F); Unroll(L); VerifyLoopAnalyses(F);}

Pass Structure

VerifyLCSSA(F);VerifyLoopInfo(F);VerifyLoopSimplify(F);

Page 51: LLVMDev 2016 - Loop Passes - Adding New Features While

Conclusion• Use verifiers

• Test extensively

• Be aware of technical debt

Page 52: LLVMDev 2016 - Loop Passes - Adding New Features While

Thank you!

Page 53: LLVMDev 2016 - Loop Passes - Adding New Features While

Q&A