diff options
author | Vikram S. Adve <vadve@cs.uiuc.edu> | 2003-07-06 20:13:59 +0000 |
---|---|---|
committer | Vikram S. Adve <vadve@cs.uiuc.edu> | 2003-07-06 20:13:59 +0000 |
commit | d09c4c34c0d0eac5cf49b25918f8d94b13a1d1b2 (patch) | |
tree | 147c6f1a548e1e420ddee10eda7e0179bc23644a /llvm/lib/Target/Sparc/SparcRegClassInfo.cpp | |
parent | 95b36820bb18ee5747a06838916ed3925a1763c8 (diff) | |
download | bcm5719-llvm-d09c4c34c0d0eac5cf49b25918f8d94b13a1d1b2.tar.gz bcm5719-llvm-d09c4c34c0d0eac5cf49b25918f8d94b13a1d1b2.zip |
Major bug fix though it happened rarely (only on a compare after an
integer overflow):
We need to use %icc and not %xcc for comparisons on 32-bit or smaller
integer values.
llvm-svn: 7111
Diffstat (limited to 'llvm/lib/Target/Sparc/SparcRegClassInfo.cpp')
-rw-r--r-- | llvm/lib/Target/Sparc/SparcRegClassInfo.cpp | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/llvm/lib/Target/Sparc/SparcRegClassInfo.cpp b/llvm/lib/Target/Sparc/SparcRegClassInfo.cpp index 63b39c16249..1640dcab6c6 100644 --- a/llvm/lib/Target/Sparc/SparcRegClassInfo.cpp +++ b/llvm/lib/Target/Sparc/SparcRegClassInfo.cpp @@ -112,6 +112,47 @@ void SparcIntRegClass::colorIGNode(IGNode * Node, LR->markForSpill(); // no color found - must spill } +//----------------------------------------------------------------------------- +// Int CC Register Class - method for coloring a node in the interference graph. +// +// Algorithm: +// +// If the single int CC register is used (either as icc or xcc) +// mark the LR for spilling +// else { +// if (the LR is a 64-bit comparison) use %xcc +// else /*32-bit or smaller*/ use %icc +// } +// +// Note: The third name (%ccr) is essentially an assembly mnemonic and +// depends solely on the opcode, so the name can be chosen in EmitAssembly. +//----------------------------------------------------------------------------- +void SparcIntCCRegClass::colorIGNode(IGNode *Node, + std::vector<bool> &IsColorUsedArr) const +{ + if (IsColorUsedArr[xcc] && IsColorUsedArr[icc]) + Node->getParentLR()->markForSpill(); + else { + // Choose whether to use %xcc or %icc based on type of value compared + const LiveRange* ccLR = Node->getParentLR(); + const Type* setCCType = (* ccLR->begin())->getType(); // any Value in LR + assert(setCCType->isIntegral()); + int ccReg = (setCCType == Type::LongTy)? xcc : icc; + +#ifndef NDEBUG + // Let's just make sure values of two different types have not been + // coalesced into this LR. + for (ValueSet::const_iterator I=ccLR->begin(), E=ccLR->end(); I != E; ++I) + assert(setCCType->isIntegral() && + ((ccReg == xcc && (*I)->getType() == Type::LongTy) || + (ccReg == icc && (*I)->getType() != Type::LongTy)) + && "Comparisons needing different intCC regs coalesced in LR!"); +#endif + + Node->setColor(ccReg); // only one int cc reg is available + } +} + //----------------------------------------------------------------------------- // Float Register Class - method for coloring a node in the interference graph. |