Skip to content
This repository was archived by the owner on Jan 7, 2023. It is now read-only.

Commit dc93abd

Browse files
pmistryintelgfxbot
authored andcommitted
loop invariant floating point division instruction were not getting propagated out of loop. This more recent patch from LLVM trunk addresses the issue. Hence porting the same along with dependent patches
Change-Id: I42a1d8ed6ac94d954a18c644731e8e2dc653fa9e
1 parent 78561a1 commit dc93abd

File tree

2 files changed

+129
-0
lines changed

2 files changed

+129
-0
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# Description : FDiv is replaced with multiplication by reciprocal and invariant
2+
# reciprocal is hoisted out of the loop, while multiplication remains
3+
# even if invariant.
4+
5+
6+
diff -Naur --strip-trailing-cr a/lib/Transforms/Scalar/LICM.cpp b/lib/Transforms/Scalar/LICM.cpp
7+
--- a/lib/Transforms/Scalar/LICM.cpp 2018-08-09 14:04:49.868088200 -0700
8+
+++ b/lib/Transforms/Scalar/LICM.cpp 2018-08-09 13:57:15.100467100 -0700
9+
@@ -435,59 +435,72 @@
10+
// Only need to process the contents of this block if it is not part of a
11+
// subloop (which would already have been processed).
12+
13+
- if (!inSubLoop(BB, CurLoop, LI))
14+
- for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E;) {
15+
- Instruction &I = *II++;
16+
- // Try constant folding this instruction. If all the operands are
17+
- // constants, it is technically hoistable, but it would be better to
18+
- // just fold it.
19+
- if (Constant *C = ConstantFoldInstruction(
20+
- &I, I.getModule()->getDataLayout(), TLI)) {
21+
- DEBUG(dbgs() << "LICM folding inst: " << I << " --> " << *C << '\n');
22+
- CurAST->copyValue(&I, C);
23+
- I.replaceAllUsesWith(C);
24+
- if (isInstructionTriviallyDead(&I, TLI)) {
25+
- CurAST->deleteValue(&I);
26+
- I.eraseFromParent();
27+
- }
28+
- Changed = true;
29+
- continue;
30+
- }
31+
+ if (inSubLoop(BB, CurLoop, LI))
32+
+ continue;
33+
34+
- // Attempt to remove floating point division out of the loop by
35+
- // converting it to a reciprocal multiplication.
36+
- if (I.getOpcode() == Instruction::FDiv &&
37+
- CurLoop->isLoopInvariant(I.getOperand(1)) &&
38+
- I.hasAllowReciprocal()) {
39+
- auto Divisor = I.getOperand(1);
40+
- auto One = llvm::ConstantFP::get(Divisor->getType(), 1.0);
41+
- auto ReciprocalDivisor = BinaryOperator::CreateFDiv(One, Divisor);
42+
- ReciprocalDivisor->setFastMathFlags(I.getFastMathFlags());
43+
- ReciprocalDivisor->insertBefore(&I);
44+
-
45+
- auto Product =
46+
- BinaryOperator::CreateFMul(I.getOperand(0), ReciprocalDivisor);
47+
- Product->setFastMathFlags(I.getFastMathFlags());
48+
- Product->insertAfter(&I);
49+
- I.replaceAllUsesWith(Product);
50+
+ // Keep track of whether the prefix of instructions visited so far are such
51+
+ // that the next instruction visited is guaranteed to execute if the loop
52+
+ // is entered.
53+
+ bool IsMustExecute = CurLoop->getHeader() == BB;
54+
+
55+
+ for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E;) {
56+
+ Instruction &I = *II++;
57+
+ // Try constant folding this instruction. If all the operands are
58+
+ // constants, it is technically hoistable, but it would be better to
59+
+ // just fold it.
60+
+ if (Constant *C = ConstantFoldInstruction(
61+
+ &I, I.getModule()->getDataLayout(), TLI)) {
62+
+ DEBUG(dbgs() << "LICM folding inst: " << I << " --> " << *C << '\n');
63+
+ CurAST->copyValue(&I, C);
64+
+ I.replaceAllUsesWith(C);
65+
+ if (isInstructionTriviallyDead(&I, TLI)) {
66+
+ CurAST->deleteValue(&I);
67+
I.eraseFromParent();
68+
-
69+
- hoist(*ReciprocalDivisor, DT, CurLoop, SafetyInfo, ORE);
70+
- Changed = true;
71+
- continue;
72+
}
73+
+ Changed = true;
74+
+ continue;
75+
+ }
76+
+
77+
+ // Try hoisting the instruction out to the preheader. We can only do
78+
+ // this if all of the operands of the instruction are loop invariant and
79+
+ // if it is safe to hoist the instruction.
80+
+ //
81+
+ if (CurLoop->hasLoopInvariantOperands(&I) &&
82+
+ canSinkOrHoistInst(I, AA, DT, CurLoop, CurAST, SafetyInfo, ORE) &&
83+
+ (IsMustExecute ||
84+
+ isSafeToExecuteUnconditionally(
85+
+ I, DT, CurLoop, SafetyInfo, ORE,
86+
+ CurLoop->getLoopPreheader()->getTerminator()))) {
87+
+ Changed |= hoist(I, DT, CurLoop, SafetyInfo, ORE);
88+
+ continue;
89+
+ }
90+
91+
- // Try hoisting the instruction out to the preheader. We can only do
92+
- // this if all of the operands of the instruction are loop invariant and
93+
- // if it is safe to hoist the instruction.
94+
- //
95+
- if (CurLoop->hasLoopInvariantOperands(&I) &&
96+
- canSinkOrHoistInst(I, AA, DT, CurLoop, CurAST, SafetyInfo, ORE) &&
97+
- isSafeToExecuteUnconditionally(
98+
- I, DT, CurLoop, SafetyInfo, ORE,
99+
- CurLoop->getLoopPreheader()->getTerminator()))
100+
- Changed |= hoist(I, DT, CurLoop, SafetyInfo, ORE);
101+
+ // Attempt to remove floating point division out of the loop by
102+
+ // converting it to a reciprocal multiplication.
103+
+ if (I.getOpcode() == Instruction::FDiv &&
104+
+ CurLoop->isLoopInvariant(I.getOperand(1)) &&
105+
+ I.hasAllowReciprocal()) {
106+
+ auto Divisor = I.getOperand(1);
107+
+ auto One = llvm::ConstantFP::get(Divisor->getType(), 1.0);
108+
+ auto ReciprocalDivisor = BinaryOperator::CreateFDiv(One, Divisor);
109+
+ ReciprocalDivisor->setFastMathFlags(I.getFastMathFlags());
110+
+ ReciprocalDivisor->insertBefore(&I);
111+
+
112+
+ auto Product =
113+
+ BinaryOperator::CreateFMul(I.getOperand(0), ReciprocalDivisor);
114+
+ Product->setFastMathFlags(I.getFastMathFlags());
115+
+ Product->insertAfter(&I);
116+
+ I.replaceAllUsesWith(Product);
117+
+ I.eraseFromParent();
118+
+
119+
+ hoist(*ReciprocalDivisor, DT, CurLoop, SafetyInfo, ORE);
120+
+ Changed = true;
121+
+ continue;
122+
}
123+
+
124+
+ if (IsMustExecute)
125+
+ IsMustExecute = isGuaranteedToTransferExecutionToSuccessor(&I);
126+
+ }
127+
}
128+
129+
return Changed;

0 commit comments

Comments
 (0)