mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-27 15:02:16 +00:00
Implement a fixme. The helps loops that have induction variables of different
types in them. Instead of creating an induction variable for all types, it creates a single induction variable and casts to the other sizes. This generates this code: no_exit: ; preds = %entry, %no_exit %indvar = phi uint [ %indvar.next, %no_exit ], [ 0, %entry ] ; <uint> [#uses=4] *** %j.0.0 = cast uint %indvar to short ; <short> [#uses=1] %indvar = cast uint %indvar to int ; <int> [#uses=1] %tmp.7 = getelementptr short* %P, uint %indvar ; <short*> [#uses=1] store short %j.0.0, short* %tmp.7 %inc.0 = add int %indvar, 1 ; <int> [#uses=2] %tmp.2 = setlt int %inc.0, %N ; <bool> [#uses=1] %indvar.next = add uint %indvar, 1 ; <uint> [#uses=1] br bool %tmp.2, label %no_exit, label %loopexit instead of: no_exit: ; preds = %entry, %no_exit %indvar = phi ushort [ %indvar.next, %no_exit ], [ 0, %entry ] ; <ushort> [#uses=2] *** %indvar = phi uint [ %indvar.next, %no_exit ], [ 0, %entry ] ; <uint> [#uses=3] %indvar = cast uint %indvar to int ; <int> [#uses=1] %indvar = cast ushort %indvar to short ; <short> [#uses=1] %tmp.7 = getelementptr short* %P, uint %indvar ; <short*> [#uses=1] store short %indvar, short* %tmp.7 %inc.0 = add int %indvar, 1 ; <int> [#uses=2] %tmp.2 = setlt int %inc.0, %N ; <bool> [#uses=1] %indvar.next = add uint %indvar, 1 *** %indvar.next = add ushort %indvar, 1 br bool %tmp.2, label %no_exit, label %loopexit This is an improvement in register pressure, but probably doesn't happen that often. The more important fix will be to get rid of the redundant add. llvm-svn: 13101
This commit is contained in:
parent
7d02bae5d8
commit
a3e2004609
@ -390,10 +390,8 @@ void IndVarSimplify::runOnLoop(Loop *L) {
|
|||||||
// Compute the type of the largest recurrence expression.
|
// Compute the type of the largest recurrence expression.
|
||||||
//
|
//
|
||||||
const Type *LargestType = IndVars[0].first->getType();
|
const Type *LargestType = IndVars[0].first->getType();
|
||||||
bool DifferingSizes = false;
|
|
||||||
for (unsigned i = 1, e = IndVars.size(); i != e; ++i) {
|
for (unsigned i = 1, e = IndVars.size(); i != e; ++i) {
|
||||||
const Type *Ty = IndVars[i].first->getType();
|
const Type *Ty = IndVars[i].first->getType();
|
||||||
DifferingSizes |= Ty->getPrimitiveSize() != LargestType->getPrimitiveSize();
|
|
||||||
if (Ty->getPrimitiveSize() > LargestType->getPrimitiveSize())
|
if (Ty->getPrimitiveSize() > LargestType->getPrimitiveSize())
|
||||||
LargestType = Ty;
|
LargestType = Ty;
|
||||||
}
|
}
|
||||||
@ -411,30 +409,35 @@ void IndVarSimplify::runOnLoop(Loop *L) {
|
|||||||
if (!isa<SCEVCouldNotCompute>(IterationCount))
|
if (!isa<SCEVCouldNotCompute>(IterationCount))
|
||||||
LinearFunctionTestReplace(L, IterationCount, Rewriter);
|
LinearFunctionTestReplace(L, IterationCount, Rewriter);
|
||||||
|
|
||||||
#if 0
|
|
||||||
// If there were induction variables of other sizes, cast the primary
|
|
||||||
// induction variable to the right size for them, avoiding the need for the
|
|
||||||
// code evaluation methods to insert induction variables of different sizes.
|
|
||||||
// FIXME!
|
|
||||||
if (DifferingSizes) {
|
|
||||||
std::map<unsigned, Value*> InsertedSizes;
|
|
||||||
for (unsigned i = 0, e = IndVars.size(); i != e; ++i) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Now that we have a canonical induction variable, we can rewrite any
|
// Now that we have a canonical induction variable, we can rewrite any
|
||||||
// recurrences in terms of the induction variable. Start with the auxillary
|
// recurrences in terms of the induction variable. Start with the auxillary
|
||||||
// induction variables, and recursively rewrite any of their uses.
|
// induction variables, and recursively rewrite any of their uses.
|
||||||
BasicBlock::iterator InsertPt = Header->begin();
|
BasicBlock::iterator InsertPt = Header->begin();
|
||||||
while (isa<PHINode>(InsertPt)) ++InsertPt;
|
while (isa<PHINode>(InsertPt)) ++InsertPt;
|
||||||
|
|
||||||
|
// If there were induction variables of other sizes, cast the primary
|
||||||
|
// induction variable to the right size for them, avoiding the need for the
|
||||||
|
// code evaluation methods to insert induction variables of different sizes.
|
||||||
|
std::map<unsigned, Value*> InsertedSizes;
|
||||||
|
InsertedSizes[LargestType->getPrimitiveSize()] = IndVar;
|
||||||
while (!IndVars.empty()) {
|
while (!IndVars.empty()) {
|
||||||
PHINode *PN = IndVars.back().first;
|
PHINode *PN = IndVars.back().first;
|
||||||
Value *NewVal = Rewriter.ExpandCodeFor(IndVars.back().second, InsertPt,
|
|
||||||
PN->getType());
|
const Type *Ty = PN->getType()->getUnsignedVersion();
|
||||||
|
Value *&IV = InsertedSizes[Ty->getPrimitiveSize()];
|
||||||
|
if (IV == 0) {
|
||||||
|
// Insert a new cast instruction, which will hold this recurrence.
|
||||||
|
std::string Name = PN->getName();
|
||||||
|
PN->setName("");
|
||||||
|
IV = new CastInst(IndVar, Ty, Name, InsertPt);
|
||||||
|
}
|
||||||
|
|
||||||
|
Value *V = IV;
|
||||||
|
if (PN->getType() != Ty)
|
||||||
|
V = new CastInst(V, PN->getType(), V->getName(), InsertPt);
|
||||||
|
|
||||||
// Replace the old PHI Node with the inserted computation.
|
// Replace the old PHI Node with the inserted computation.
|
||||||
PN->replaceAllUsesWith(NewVal);
|
PN->replaceAllUsesWith(V);
|
||||||
DeadInsts.insert(PN);
|
DeadInsts.insert(PN);
|
||||||
IndVars.pop_back();
|
IndVars.pop_back();
|
||||||
++NumRemoved;
|
++NumRemoved;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user