summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Sparc/SparcRegClassInfo.cpp
diff options
context:
space:
mode:
authorVikram S. Adve <vadve@cs.uiuc.edu>2003-07-06 20:13:59 +0000
committerVikram S. Adve <vadve@cs.uiuc.edu>2003-07-06 20:13:59 +0000
commitd09c4c34c0d0eac5cf49b25918f8d94b13a1d1b2 (patch)
tree147c6f1a548e1e420ddee10eda7e0179bc23644a /llvm/lib/Target/Sparc/SparcRegClassInfo.cpp
parent95b36820bb18ee5747a06838916ed3925a1763c8 (diff)
downloadbcm5719-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.cpp41
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.
OpenPOWER on IntegriCloud