From lattner at cs.uiuc.edu Mon May 26 13:39:01 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Mon May 26 13:39:01 2003
Subject: [llvm-commits] CVS: llvm/www/pubs/2003-05-01-GCCSummit2003.html
Message-ID: <200305261838.NAA04738@tank.cs.uiuc.edu>
Changes in directory llvm/www/pubs:
2003-05-01-GCCSummit2003.html updated: 1.4 -> 1.5
---
Log message:
Update to include links to the presentation
---
Diffs of the changes:
Index: llvm/www/pubs/2003-05-01-GCCSummit2003.html
diff -u llvm/www/pubs/2003-05-01-GCCSummit2003.html:1.4 llvm/www/pubs/2003-05-01-GCCSummit2003.html:1.5
--- llvm/www/pubs/2003-05-01-GCCSummit2003.html:1.4 Fri May 2 12:33:50 2003
+++ llvm/www/pubs/2003-05-01-GCCSummit2003.html Mon May 26 13:37:55 2003
@@ -46,6 +46,12 @@
Architecture for a Next-Generation GCC (PDF)
+Presentation:
+
+
Bibtex Entry:
@inproceedings{LattnerAdve:GCCSummit03,
From lattner at cs.uiuc.edu Mon May 26 13:40:01 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Mon May 26 13:40:01 2003
Subject: [llvm-commits] CVS: llvm/www/pubs/2003-05-01-GCCSummit2003.html
Message-ID: <200305261839.NAA04770@tank.cs.uiuc.edu>
Changes in directory llvm/www/pubs:
2003-05-01-GCCSummit2003.html updated: 1.5 -> 1.6
---
Log message:
Correct link
---
Diffs of the changes:
Index: llvm/www/pubs/2003-05-01-GCCSummit2003.html
diff -u llvm/www/pubs/2003-05-01-GCCSummit2003.html:1.5 llvm/www/pubs/2003-05-01-GCCSummit2003.html:1.6
--- llvm/www/pubs/2003-05-01-GCCSummit2003.html:1.5 Mon May 26 13:37:55 2003
+++ llvm/www/pubs/2003-05-01-GCCSummit2003.html Mon May 26 13:39:42 2003
@@ -48,8 +48,8 @@
Presentation:
Bibtex Entry:
From vadve at cs.uiuc.edu Mon May 26 17:04:00 2003
From: vadve at cs.uiuc.edu (Vikram Adve)
Date: Mon May 26 17:04:00 2003
Subject: [llvm-commits] CVS: llvm/test/Programs/SingleSource/UnitTests/2003-05-26-Shorts.c
Message-ID: <200305262203.RAA29070@trinity.cs.uiuc.edu>
Changes in directory llvm/test/Programs/SingleSource/UnitTests:
2003-05-26-Shorts.c added (r1.1)
---
Log message:
Unit test for handling of short signed and unsigned integers
less than a word size, especially in -, * and / operations.
---
Diffs of the changes:
Index: llvm/test/Programs/SingleSource/UnitTests/2003-05-26-Shorts.c
diff -c /dev/null llvm/test/Programs/SingleSource/UnitTests/2003-05-26-Shorts.c:1.1
*** /dev/null Mon May 26 17:03:36 2003
--- llvm/test/Programs/SingleSource/UnitTests/2003-05-26-Shorts.c Mon May 26 17:03:25 2003
***************
*** 0 ****
--- 1,54 ----
+ /*
+ * This test stresses masking and sign-extension for operations on
+ * signed and unsigned types less than the machine integer reg. size.
+ * Several things have to happen correctly:
+ * -- correct constant folding if it is done at compile-time
+ * -- correct sign-extensions during native code generation for -, * and /.
+ * -- correct handling of high bits during native code generation for
+ * a sequence of operations involving -, * and /.
+ */
+ #include
+ #include
+ #include
+
+ int
+ main(int argc, char** argv)
+ {
+ unsigned long UL = 0xafafafafc5c5b8a3;
+ long L = (long) UL;
+
+ unsigned int ui = (unsigned int) UL; /* 0xc5c5b8a3 = 3318069411 */
+ int i = (int) UL; /* 0xc5c5b8a3 = -976897885 */
+
+ unsigned short us = (unsigned short) UL; /* 0xb8a3 = 47267 */
+ short s = (short) UL; /* 0xb8a3 = -18269 */
+
+ uint8_t ub = (uint8_t) UL; /* 0xa3 = 163 */
+ int8_t b = ( int8_t) UL; /* 0xa3 = -93 */
+
+ printf(" ui = %u (0x%x)\t\tUL-ui = %ld (0x%x)\n", ui, ui, UL-ui, UL-ui);
+ printf("ui*ui = %u (0x%x)\t UL/ui = %ld (0x%x)\n\n",
+ (unsigned int) ui*ui, (unsigned int) ui*ui, UL/ui, UL/ui);
+
+ printf(" i = %d (0x%x)\tL-i = %ld (0x%x)\n", i, i, L-i, L-i);
+ printf(" i* i = %d (0x%x)\tL/ i = %ld (0x%x)\n\n",
+ (int) i*i, (int) i*i, L/i, L/i);
+
+ printf("us = %u (0x%x)\t\tUL-us = %ld (0x%x)\n", us, us, UL-us, UL-us);
+ printf("us*us = %u (0x%x)\t UL/us = %ld (0x%x)\n\n",
+ (unsigned short) us*us, (unsigned short) us*us, UL/us, UL/us);
+
+ printf(" s = %d (0x%x)\tL-s = %ld (0x%x)\n", s, s, L-s, L-s);
+ printf(" s* s = %d (0x%x)\tL/ s = %ld (0x%x)\n\n",
+ (short) s*s, (short) s*s, L/s, L/s);
+
+ printf("ub = %u (0x%x)\t\tUL-ub = %ld (0x%x)\n", ub, ub, UL-ub, UL-ub);
+ printf("ub*ub = %u (0x%x)\t\tUL/ub = %ld (0x%x)\n\n",
+ (uint8_t) ub*ub, (uint8_t) ub*ub, UL/ub, UL/ub);
+
+ printf(" b = %d (0x%x)\t\tL-b = %ld (0x%x)\n", b, b, L-b, L-b);
+ printf(" b* b = %d (0x%x)\t\t\tL/b = %ld (0x%x)\n\n",
+ (int8_t) b*b, (int8_t) b*b, L/b, L/b);
+
+ return 0;
+ }
From lattner at cs.uiuc.edu Mon May 26 18:42:01 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Mon May 26 18:42:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Message-ID: <200305262341.SAA21498@apoc.cs.uiuc.edu>
Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.83 -> 1.84
---
Log message:
Fix bug: InstCombine/2003-05-26-CastMiscompile.ll
---
Diffs of the changes:
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.83 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.84
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.83 Thu May 22 14:07:21 2003
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon May 26 18:41:32 2003
@@ -897,7 +897,7 @@
CSrc->getType()->getPrimitiveSize() < CI.getType()->getPrimitiveSize()){
assert(CSrc->getType() != Type::ULongTy &&
"Cannot have type bigger than ulong!");
- unsigned AndValue = (1U << CSrc->getType()->getPrimitiveSize()*8)-1;
+ uint64_t AndValue = (1ULL << CSrc->getType()->getPrimitiveSize()*8)-1;
Constant *AndOp = ConstantUInt::get(CI.getType(), AndValue);
return BinaryOperator::create(Instruction::And, CSrc->getOperand(0),
AndOp);
From lattner at cs.uiuc.edu Mon May 26 18:42:01 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Mon May 26 18:42:01 2003
Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/2003-05-26-CastMiscompile.ll
Message-ID: <200305262341.SAA21488@apoc.cs.uiuc.edu>
Changes in directory llvm/test/Regression/Transforms/InstCombine:
2003-05-26-CastMiscompile.ll added (r1.1)
---
Log message:
New testcase
---
Diffs of the changes:
Index: llvm/test/Regression/Transforms/InstCombine/2003-05-26-CastMiscompile.ll
diff -c /dev/null llvm/test/Regression/Transforms/InstCombine/2003-05-26-CastMiscompile.ll:1.1
*** /dev/null Mon May 26 18:41:23 2003
--- llvm/test/Regression/Transforms/InstCombine/2003-05-26-CastMiscompile.ll Mon May 26 18:41:13 2003
***************
*** 0 ****
--- 1,7 ----
+ ; RUN: as < %s | opt -instcombine | dis | grep 4294967295
+
+ ulong %test(ulong %Val) {
+ %tmp.3 = cast ulong %Val to uint ; [#uses=1]
+ %tmp.8 = cast uint %tmp.3 to ulong ; [#uses=1]
+ ret ulong %tmp.8
+ }
From vadve at cs.uiuc.edu Mon May 26 19:03:01 2003
From: vadve at cs.uiuc.edu (Vikram Adve)
Date: Mon May 26 19:03:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/EmitAssembly.cpp SparcInstrSelection.cpp SparcInternals.h SparcOptInfo.cpp SparcRegClassInfo.h SparcRegInfo.cpp
Message-ID: <200305270002.TAA30652@psmith.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
EmitAssembly.cpp updated: 1.75 -> 1.76
SparcInstrSelection.cpp updated: 1.93 -> 1.94
SparcInternals.h updated: 1.84 -> 1.85
SparcOptInfo.cpp updated: 1.6 -> 1.7
SparcRegClassInfo.h updated: 1.15 -> 1.16
SparcRegInfo.cpp updated: 1.93 -> 1.94
---
Log message:
Added special register class containing (for now) %fsr.
Fixed spilling of %fcc[0-3] which are part of %fsr.
Moved some machine-independent reg-class code to class TargetRegInfo
from SparcReg{Class,}Info.
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/EmitAssembly.cpp
diff -u llvm/lib/Target/Sparc/EmitAssembly.cpp:1.75 llvm/lib/Target/Sparc/EmitAssembly.cpp:1.76
--- llvm/lib/Target/Sparc/EmitAssembly.cpp:1.75 Sun May 25 16:59:09 2003
+++ llvm/lib/Target/Sparc/EmitAssembly.cpp Mon May 26 19:02:22 2003
@@ -302,7 +302,7 @@
void emitMachineInst(const MachineInstr *MI);
unsigned int printOperands(const MachineInstr *MI, unsigned int opNum);
- void printOneOperand(const MachineOperand &Op);
+ void printOneOperand(const MachineOperand &Op, MachineOpCode opCode);
bool OpIsBranchTargetLabel(const MachineInstr *MI, unsigned int opNum);
bool OpIsMemoryAddressBase(const MachineInstr *MI, unsigned int opNum);
@@ -341,10 +341,10 @@
}
-#define PrintOp1PlusOp2(mop1, mop2) \
- printOneOperand(mop1); \
+#define PrintOp1PlusOp2(mop1, mop2, opCode) \
+ printOneOperand(mop1, opCode); \
toAsm << "+"; \
- printOneOperand(mop2);
+ printOneOperand(mop2, opCode);
unsigned int
SparcFunctionAsmPrinter::printOperands(const MachineInstr *MI,
@@ -354,26 +354,26 @@
if (OpIsBranchTargetLabel(MI, opNum))
{
- PrintOp1PlusOp2(mop, MI->getOperand(opNum+1));
+ PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpCode());
return 2;
}
else if (OpIsMemoryAddressBase(MI, opNum))
{
toAsm << "[";
- PrintOp1PlusOp2(mop, MI->getOperand(opNum+1));
+ PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpCode());
toAsm << "]";
return 2;
}
else
{
- printOneOperand(mop);
+ printOneOperand(mop, MI->getOpCode());
return 1;
}
}
-
void
-SparcFunctionAsmPrinter::printOneOperand(const MachineOperand &mop)
+SparcFunctionAsmPrinter::printOneOperand(const MachineOperand &mop,
+ MachineOpCode opCode)
{
bool needBitsFlag = true;
@@ -394,13 +394,13 @@
case MachineOperand::MO_CCRegister:
case MachineOperand::MO_MachineRegister:
{
- int RegNum = (int)mop.getAllocatedRegNum();
+ int regNum = (int)mop.getAllocatedRegNum();
- // better to print code with NULL registers than to die
- if (RegNum == Target.getRegInfo().getInvalidRegNum()) {
+ if (regNum == Target.getRegInfo().getInvalidRegNum()) {
+ // better to print code with NULL registers than to die
toAsm << "";
} else {
- toAsm << "%" << Target.getRegInfo().getUnifiedRegName(RegNum);
+ toAsm << "%" << Target.getRegInfo().getUnifiedRegName(regNum);
}
break;
}
Index: llvm/lib/Target/Sparc/SparcInstrSelection.cpp
diff -u llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.93 llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.94
--- llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.93 Sun May 25 16:59:47 2003
+++ llvm/lib/Target/Sparc/SparcInstrSelection.cpp Mon May 26 19:02:22 2003
@@ -1318,8 +1318,8 @@
for (unsigned i=0,numOps=minstr->getNumImplicitRefs(); igetImplicitRef(i) == unusedOp)
minstr->setImplicitRef(i, fwdOp,
- minstr->implicitRefIsDefined(i),
- minstr->implicitRefIsDefinedAndUsed(i));
+ minstr->getImplicitOp(i).opIsDefOnly(),
+ minstr->getImplicitOp(i).opIsDefAndUse());
}
}
}
Index: llvm/lib/Target/Sparc/SparcInternals.h
diff -u llvm/lib/Target/Sparc/SparcInternals.h:1.84 llvm/lib/Target/Sparc/SparcInternals.h:1.85
--- llvm/lib/Target/Sparc/SparcInternals.h:1.84 Sun May 25 10:59:47 2003
+++ llvm/lib/Target/Sparc/SparcInternals.h Mon May 26 19:02:22 2003
@@ -255,7 +255,8 @@
IntRegClassID, // Integer
FloatRegClassID, // Float (both single/double)
IntCCRegClassID, // Int Condition Code
- FloatCCRegClassID // Float Condition code
+ FloatCCRegClassID, // Float Condition code
+ SpecialRegClassID // Special (unallocated) registers
};
@@ -268,7 +269,8 @@
FPSingleRegType,
FPDoubleRegType,
IntCCRegType,
- FloatCCRegType
+ FloatCCRegType,
+ SpecialRegType
};
// **** WARNING: If the above enum order is changed, also modify
@@ -308,6 +310,9 @@
std::vector& AddedInstrnsBefore)
const;
+ // Get the register type for a register identified different ways.
+ // The first function is a helper used by the all the hoter functions.
+ int getRegTypeForClassAndType(unsigned regClassID, const Type* type) const;
int getRegType(const Type* type) const;
int getRegType(const LiveRange *LR) const;
int getRegType(int unifiedRegNum) const;
@@ -352,7 +357,6 @@
// To find the register class to which a specified register belongs
//
- unsigned getRegClassIDOfReg(int unifiedRegNum) const;
unsigned getRegClassIDOfRegType(int regType) const;
// getZeroRegNum - returns the register that contains always zero this is the
@@ -403,56 +407,8 @@
// method used for printing a register for debugging purposes
//
- static void printReg(const LiveRange *LR);
-
- // Each register class has a seperate space for register IDs. To convert
- // a regId in a register class to a common Id, or vice versa,
- // we use the folloing methods.
- //
- // This method provides a unique number for each register
- inline int getUnifiedRegNum(unsigned regClassID, int reg) const {
-
- if (regClassID == IntRegClassID) {
- assert(reg < 32 && "Invalid reg. number");
- return reg;
- }
- else if (regClassID == FloatRegClassID) {
- assert(reg < 64 && "Invalid reg. number");
- return reg + 32; // we have 32 int regs
- }
- else if (regClassID == FloatCCRegClassID) {
- assert(reg < 4 && "Invalid reg. number");
- return reg + 32 + 64; // 32 int, 64 float
- }
- else if (regClassID == IntCCRegClassID ) {
- assert(reg == 0 && "Invalid reg. number");
- return reg + 4+ 32 + 64; // only one int CC reg
- }
- else if (reg==InvalidRegNum) {
- return InvalidRegNum;
- }
- else
- assert(0 && "Invalid register class");
- return 0;
- }
-
- // This method converts the unified number to the number in its class,
- // and returns the class ID in regClassID.
- inline int getClassRegNum(int ureg, unsigned& regClassID) const {
- if (ureg < 32) { regClassID = IntRegClassID; return ureg; }
- else if (ureg < 32+64) { regClassID = FloatRegClassID; return ureg-32; }
- else if (ureg < 4 +96) { regClassID = FloatCCRegClassID; return ureg-96; }
- else if (ureg < 1 +100) { regClassID = IntCCRegClassID; return ureg-100;}
- else if (ureg == InvalidRegNum) { return InvalidRegNum; }
- else { assert(0 && "Invalid unified register number"); }
- return 0;
- }
+ void printReg(const LiveRange *LR) const;
- // Returns the assembly-language name of the specified machine register.
- //
- virtual const char * const getUnifiedRegName(int reg) const;
-
-
// returns the # of bytes of stack space allocated for each register
// type. For Sparc, currently we allocate 8 bytes on stack for all
// register types. We can optimize this later if necessary to save stack
Index: llvm/lib/Target/Sparc/SparcOptInfo.cpp
diff -u llvm/lib/Target/Sparc/SparcOptInfo.cpp:1.6 llvm/lib/Target/Sparc/SparcOptInfo.cpp:1.7
--- llvm/lib/Target/Sparc/SparcOptInfo.cpp:1.6 Tue May 20 15:32:24 2003
+++ llvm/lib/Target/Sparc/SparcOptInfo.cpp Mon May 26 19:02:22 2003
@@ -45,7 +45,7 @@
target.getRegInfo().getZeroRegNum()) ||
/* or operand otherOp == 0 */
- (MI->getOperandType(otherOp)
+ (MI->getOperand(otherOp).getType()
== MachineOperand::MO_SignExtendedImmed &&
MI->getOperand(otherOp).getImmedValue() == 0));
}
Index: llvm/lib/Target/Sparc/SparcRegClassInfo.h
diff -u llvm/lib/Target/Sparc/SparcRegClassInfo.h:1.15 llvm/lib/Target/Sparc/SparcRegClassInfo.h:1.16
--- llvm/lib/Target/Sparc/SparcRegClassInfo.h:1.15 Sat Dec 28 21:13:02 2002
+++ llvm/lib/Target/Sparc/SparcRegClassInfo.h Mon May 26 19:02:22 2003
@@ -63,7 +63,7 @@
StartOfAllRegs = o0,
};
- static const char * const getRegName(unsigned reg);
+ const char * const getRegName(unsigned reg) const;
};
@@ -104,7 +104,7 @@
StartOfAllRegs = f0,
};
- static const char * const getRegName(unsigned reg);
+ const char * const getRegName(unsigned reg) const;
};
@@ -138,7 +138,7 @@
xcc, ccr // only one is available - see the note above
};
- static const char * const getRegName(unsigned reg);
+ const char * const getRegName(unsigned reg) const;
};
@@ -146,12 +146,12 @@
//-----------------------------------------------------------------------------
// Float CC Register Class
-// Only 4 Float CC registers are available
+// Only 4 Float CC registers are available for allocation.
//-----------------------------------------------------------------------------
struct SparcFloatCCRegClass : public TargetRegClassInfo {
SparcFloatCCRegClass(unsigned ID)
- : TargetRegClassInfo(ID, 4, 4) { }
+ : TargetRegClassInfo(ID, 4, 5) { }
void colorIGNode(IGNode *Node, std::vector &IsColorUsedArr) const {
for(unsigned c = 0; c != 4; ++c)
@@ -168,10 +168,33 @@
inline bool isRegVolatile(int Reg) const { return true; }
enum {
- fcc0, fcc1, fcc2, fcc3
+ fcc0, fcc1, fcc2, fcc3, fsr // fsr is not used in allocation
+ }; // but has a name in getRegName()
+
+ const char * const getRegName(unsigned reg) const;
+};
+
+//-----------------------------------------------------------------------------
+// Sparc special register class. These registers are not used for allocation
+// but are used as arguments of some instructions.
+//-----------------------------------------------------------------------------
+
+struct SparcSpecialRegClass : public TargetRegClassInfo {
+ SparcSpecialRegClass(unsigned ID)
+ : TargetRegClassInfo(ID, 0, 1) { }
+
+ void colorIGNode(IGNode *Node, std::vector &IsColorUsedArr) const {
+ assert(0 && "SparcSpecialRegClass should never be used for allocation");
+ }
+
+ // all currently included special regs are volatile
+ inline bool isRegVolatile(int Reg) const { return true; }
+
+ enum {
+ fsr // floating point state register
};
- static const char * const getRegName(unsigned reg);
+ const char * const getRegName(unsigned reg) const;
};
#endif
Index: llvm/lib/Target/Sparc/SparcRegInfo.cpp
diff -u llvm/lib/Target/Sparc/SparcRegInfo.cpp:1.93 llvm/lib/Target/Sparc/SparcRegInfo.cpp:1.94
--- llvm/lib/Target/Sparc/SparcRegInfo.cpp:1.93 Wed May 21 12:59:06 2003
+++ llvm/lib/Target/Sparc/SparcRegInfo.cpp Mon May 26 19:02:22 2003
@@ -32,6 +32,7 @@
MachineRegClassArr.push_back(new SparcFloatRegClass(FloatRegClassID));
MachineRegClassArr.push_back(new SparcIntCCRegClass(IntCCRegClassID));
MachineRegClassArr.push_back(new SparcFloatCCRegClass(FloatCCRegClassID));
+ MachineRegClassArr.push_back(new SparcSpecialRegClass(SpecialRegClassID));
assert(SparcFloatRegClass::StartOfNonVolatileRegs == 32 &&
"32 Float regs are used for float arg passing");
@@ -75,7 +76,7 @@
"o6"
};
-const char * const SparcIntRegClass::getRegName(unsigned reg) {
+const char * const SparcIntRegClass::getRegName(unsigned reg) const {
assert(reg < NumOfAllRegs);
return IntRegNames[reg];
}
@@ -90,7 +91,7 @@
"f60", "f61", "f62", "f63"
};
-const char * const SparcFloatRegClass::getRegName(unsigned reg) {
+const char * const SparcFloatRegClass::getRegName(unsigned reg) const {
assert (reg < NumOfAllRegs);
return FloatRegNames[reg];
}
@@ -100,7 +101,7 @@
"xcc", "ccr"
};
-const char * const SparcIntCCRegClass::getRegName(unsigned reg) {
+const char * const SparcIntCCRegClass::getRegName(unsigned reg) const {
assert(reg < 2);
return IntCCRegNames[reg];
}
@@ -109,28 +110,18 @@
"fcc0", "fcc1", "fcc2", "fcc3"
};
-const char * const SparcFloatCCRegClass::getRegName(unsigned reg) {
- assert (reg < 4);
+const char * const SparcFloatCCRegClass::getRegName(unsigned reg) const {
+ assert (reg < 5);
return FloatCCRegNames[reg];
}
-// given the unified register number, this gives the name
-// for generating assembly code or debugging.
-//
-const char * const UltraSparcRegInfo::getUnifiedRegName(int reg) const {
- if( reg < 32 )
- return SparcIntRegClass::getRegName(reg);
- else if ( reg < (64 + 32) )
- return SparcFloatRegClass::getRegName( reg - 32);
- else if( reg < (64+32+4) )
- return SparcFloatCCRegClass::getRegName( reg -32 - 64);
- else if( reg < (64+32+4+2) ) // two names: %xcc and %ccr
- return SparcIntCCRegClass::getRegName( reg -32 - 64 - 4);
- else if (reg== InvalidRegNum) //****** TODO: Remove */
- return "<*NoReg*>";
- else
- assert(0 && "Invalid register number");
- return "";
+static const char * const SpecialRegNames[] = {
+ "fsr"
+};
+
+const char * const SparcSpecialRegClass::getRegName(unsigned reg) const {
+ assert (reg < 1);
+ return SpecialRegNames[reg];
}
// Get unified reg number for frame pointer
@@ -230,43 +221,34 @@
// The following 4 methods are used to find the RegType (SparcInternals.h)
// of a LiveRange, a Value, and for a given register unified reg number.
//
-int UltraSparcRegInfo::getRegType(const Type* type) const {
- unsigned regClassID = getRegClassIDOfType(type);
+int UltraSparcRegInfo::getRegTypeForClassAndType(unsigned regClassID,
+ const Type* type) const
+{
switch (regClassID) {
- case IntRegClassID: return IntRegType;
- case FloatRegClassID: {
- if (type == Type::FloatTy)
- return FPSingleRegType;
- else if (type == Type::DoubleTy)
- return FPDoubleRegType;
- assert(0 && "Unknown type in FloatRegClass");
- }
- case IntCCRegClassID: return IntCCRegType;
- case FloatCCRegClassID: return FloatCCRegType;
+ case IntRegClassID: return IntRegType;
+ case FloatRegClassID:
+ if (type == Type::FloatTy) return FPSingleRegType;
+ else if (type == Type::DoubleTy) return FPDoubleRegType;
+ assert(0 && "Unknown type in FloatRegClass"); return 0;
+ case IntCCRegClassID: return IntCCRegType;
+ case FloatCCRegClassID: return FloatCCRegType;
+ case SpecialRegClassID: return SpecialRegType;
default: assert( 0 && "Unknown reg class ID"); return 0;
}
}
-int UltraSparcRegInfo::getRegType(const LiveRange *LR) const {
- const Type* type = LR->getType();
-
- unsigned regClassID = LR->getRegClassID();
- switch (regClassID) {
- default: assert( 0 && "Unknown reg class ID");
- case IntRegClassID: return IntRegType;
- case FloatRegClassID:
- if (type == Type::FloatTy)
- return FPSingleRegType;
- else if (type == Type::DoubleTy)
- return FPDoubleRegType;
- assert(0 && "Unknown type in FloatRegClass");
- case IntCCRegClassID: return IntCCRegType;
- case FloatCCRegClassID: return FloatCCRegType;
- }
+int UltraSparcRegInfo::getRegType(const Type* type) const
+{
+ return getRegTypeForClassAndType(getRegClassIDOfType(type), type);
}
+int UltraSparcRegInfo::getRegType(const LiveRange *LR) const
+{
+ return getRegTypeForClassAndType(LR->getRegClassID(), LR->getType());
+}
-int UltraSparcRegInfo::getRegType(int unifiedRegNum) const {
+int UltraSparcRegInfo::getRegType(int unifiedRegNum) const
+{
if (unifiedRegNum < 32)
return IntRegType;
else if (unifiedRegNum < (32 + 32))
@@ -308,14 +290,6 @@
return res;
}
-// To find the register class to which a specified register belongs
-//
-unsigned UltraSparcRegInfo::getRegClassIDOfReg(int unifiedRegNum) const {
- unsigned classId = 0;
- (void) getClassRegNum(unifiedRegNum, classId);
- return classId;
-}
-
unsigned UltraSparcRegInfo::getRegClassIDOfRegType(int regType) const {
switch(regType) {
case IntRegType: return IntRegClassID;
@@ -1183,13 +1157,14 @@
cpReg2MemMI(mvec, scratchReg, DestPtrReg, Offset, IntRegType);
return;
- case FloatCCRegType:
- assert(0 && "Tell Vikram if this assertion fails: we may have to mask out the other bits here");
+ case FloatCCRegType: {
assert(target.getInstrInfo().constantFitsInImmedField(V9::STXFSR, Offset));
- MI = BuildMI(V9::STXFSR, 3).addMReg(SrcReg).addMReg(DestPtrReg)
- .addSImm(Offset);
+ unsigned fsrRegNum = getUnifiedRegNum(UltraSparcRegInfo::SpecialRegClassID,
+ SparcSpecialRegClass::fsr);
+ MI = BuildMI(V9::STXFSR, 3)
+ .addMReg(fsrRegNum).addMReg(DestPtrReg).addSImm(Offset);
break;
-
+ }
default:
assert(0 && "Unknown RegType in cpReg2MemMI");
}
@@ -1239,14 +1214,14 @@
MI = BuildMI(V9::WRCCR, 2).addMReg(scratchReg).addMReg(DestReg+1,MOTy::Def);
break;
- case FloatCCRegType:
- assert(0 && "Tell Vikram if this assertion fails: we may have to mask "
- "out the other bits here");
+ case FloatCCRegType: {
assert(target.getInstrInfo().constantFitsInImmedField(V9::LDXFSR, Offset));
+ unsigned fsrRegNum = getUnifiedRegNum(UltraSparcRegInfo::SpecialRegClassID,
+ SparcSpecialRegClass::fsr);
MI = BuildMI(V9::LDXFSR, 3).addMReg(SrcPtrReg).addSImm(Offset)
- .addMReg(DestReg, MOTy::Def);
+ .addMReg(fsrRegNum, MOTy::UseAndDef);
break;
-
+ }
default:
assert(0 && "Unknown RegType in cpMem2RegMI");
}
@@ -1462,7 +1437,7 @@
// Print the register assigned to a LR
//---------------------------------------------------------------------------
-void UltraSparcRegInfo::printReg(const LiveRange *LR) {
+void UltraSparcRegInfo::printReg(const LiveRange *LR) const {
unsigned RegClassID = LR->getRegClassID();
std::cerr << " *Node " << (LR->getUserIGNode())->getIndex();
@@ -1475,15 +1450,13 @@
std::cerr << " colored with color "<< LR->getColor();
- if (RegClassID == IntRegClassID) {
- std::cerr<< " [" << SparcIntRegClass::getRegName(LR->getColor()) << "]\n";
-
- } else if (RegClassID == FloatRegClassID) {
- std::cerr << "[" << SparcFloatRegClass::getRegName(LR->getColor());
- if( LR->getType() == Type::DoubleTy)
- std::cerr << "+" << SparcFloatRegClass::getRegName(LR->getColor()+1);
- std::cerr << "]\n";
- }
+ unsigned uRegName = getUnifiedRegNum(RegClassID, LR->getColor());
+
+ std::cerr << "[";
+ std::cerr<< getUnifiedRegName(uRegName);
+ if (RegClassID == FloatRegClassID && LR->getType() == Type::DoubleTy)
+ std::cerr << "+" << getUnifiedRegName(uRegName+1);
+ std::cerr << "]\n";
}
//---------------------------------------------------------------------------
@@ -1559,7 +1532,7 @@
// last operand is the def (unless for a store which has no def reg)
MachineOperand& DefOp = DefInst->getOperand(DefInst->getNumOperands()-1);
- if (DefOp.opIsDef() &&
+ if ((DefOp.opIsDefOnly() || DefOp.opIsDefAndUse()) &&
DefOp.getType() == MachineOperand::MO_MachineRegister) {
// If the operand in DefInst is a def ...
@@ -1576,7 +1549,7 @@
// for each inst (UseInst) that is below the DefInst do ...
MachineOperand& UseOp = UseInst->getOperand(0);
- if (!UseOp.opIsDef() &&
+ if (!UseOp.opIsDefOnly() &&
UseOp.getType() == MachineOperand::MO_MachineRegister) {
// if use is a register ...
@@ -1637,7 +1610,7 @@
PhyRegAlloc &PRA) const {
MachineOperand& UseOp = UnordInst->getOperand(0);
- if (!UseOp.opIsDef() &&
+ if (!UseOp.opIsDefOnly() &&
UseOp.getType() == MachineOperand::MO_MachineRegister) {
// for the use of UnordInst, see whether there is a defining instr
@@ -1653,7 +1626,7 @@
MachineOperand& DefOp =
OrdInst->getOperand(OrdInst->getNumOperands()-1);
- if( DefOp.opIsDef() &&
+ if( (DefOp.opIsDefOnly() || DefOp.opIsDefAndUse()) &&
DefOp.getType() == MachineOperand::MO_MachineRegister) {
//std::cerr << "\nDefining Ord Inst: " << *OrdInst;
@@ -1686,7 +1659,8 @@
// Load directly into DReg (%oy)
MachineOperand& DOp=
(UnordInst->getOperand(UnordInst->getNumOperands()-1));
- assert(DOp.opIsDef() && "Last operand is not the def");
+ assert((DOp.opIsDefOnly() || DefOp.opIsDefAndUse()) &&
+ "Last operand is not the def");
const int DReg = DOp.getMachineRegNum();
cpMem2RegMI(OrdVec, getFramePointer(), StackOff, DReg, RegType);
From vadve at cs.uiuc.edu Mon May 26 19:04:01 2003
From: vadve at cs.uiuc.edu (Vikram Adve)
Date: Mon May 26 19:04:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp
Message-ID: <200305270003.TAA30702@psmith.cs.uiuc.edu>
Changes in directory llvm/lib/Target/X86:
Printer.cpp updated: 1.34 -> 1.35
---
Log message:
Renamed opIsDef to opIsDefOnly.
---
Diffs of the changes:
Index: llvm/lib/Target/X86/Printer.cpp
diff -u llvm/lib/Target/X86/Printer.cpp:1.34 llvm/lib/Target/X86/Printer.cpp:1.35
--- llvm/lib/Target/X86/Printer.cpp:1.34 Tue Jan 14 15:59:16 2003
+++ llvm/lib/Target/X86/Printer.cpp Mon May 26 19:03:17 2003
@@ -221,7 +221,8 @@
}
} else {
unsigned i = 0;
- if (MI->getNumOperands() && MI->getOperand(0).opIsDef()) {
+ if (MI->getNumOperands() && (MI->getOperand(0).opIsDefOnly() ||
+ MI->getOperand(0).opIsDefAndUse())) {
printOp(O, MI->getOperand(0), RI);
O << " = ";
++i;
@@ -230,9 +231,11 @@
for (unsigned e = MI->getNumOperands(); i != e; ++i) {
O << " ";
- if (MI->getOperand(i).opIsDef()) O << "*";
+ if (MI->getOperand(i).opIsDefOnly() ||
+ MI->getOperand(i).opIsDefAndUse()) O << "*";
printOp(O, MI->getOperand(i), RI);
- if (MI->getOperand(i).opIsDef()) O << "*";
+ if (MI->getOperand(i).opIsDefOnly() ||
+ MI->getOperand(i).opIsDefAndUse()) O << "*";
}
}
O << "\n";
From vadve at cs.uiuc.edu Mon May 26 19:06:01 2003
From: vadve at cs.uiuc.edu (Vikram Adve)
Date: Mon May 26 19:06:01 2003
Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAlloc/LiveRangeInfo.cpp PhyRegAlloc.cpp
Message-ID: <200305270005.TAA31234@psmith.cs.uiuc.edu>
Changes in directory llvm/lib/CodeGen/RegAlloc:
LiveRangeInfo.cpp updated: 1.39 -> 1.40
PhyRegAlloc.cpp updated: 1.94 -> 1.95
---
Log message:
(1) Added special register class containing (for now) %fsr.
Fixed spilling of %fcc[0-3] which are part of %fsr.
(2) Moved some machine-independent reg-class code to class TargetRegInfo
from SparcReg{Class,}Info.
(3) Renamed MachienOperand::opIsDef to MachineOperand::opIsDefOnly()
and related functions and flags. Fixed several bugs where only
"isDef" was being checked, not "isDefAndUse".
---
Diffs of the changes:
Index: llvm/lib/CodeGen/RegAlloc/LiveRangeInfo.cpp
diff -u llvm/lib/CodeGen/RegAlloc/LiveRangeInfo.cpp:1.39 llvm/lib/CodeGen/RegAlloc/LiveRangeInfo.cpp:1.40
--- llvm/lib/CodeGen/RegAlloc/LiveRangeInfo.cpp:1.39 Wed Jan 15 15:14:01 2003
+++ llvm/lib/CodeGen/RegAlloc/LiveRangeInfo.cpp Mon May 26 19:05:23 2003
@@ -170,7 +170,7 @@
// for each operand that is defined by the instruction
for (MachineInstr::val_op_iterator OpI = MInst->begin(),
OpE = MInst->end(); OpI != OpE; ++OpI)
- if (OpI.isDef()) {
+ if (OpI.isDefOnly() || OpI.isDefAndUse()) {
const Value *Def = *OpI;
bool isCC = (OpI.getMachineOperand().getType()
== MachineOperand::MO_CCRegister);
@@ -180,7 +180,8 @@
// iterate over implicit MI operands and create a new LR
// for each operand that is defined by the instruction
for (unsigned i = 0; i < MInst->getNumImplicitRefs(); ++i)
- if (MInst->implicitRefIsDefined(i)) {
+ if (MInst->getImplicitOp(i).opIsDefOnly() ||
+ MInst->getImplicitOp(i).opIsDefAndUse()) {
const Value *Def = MInst->getImplicitRef(i);
createOrAddToLiveRange(Def, /*isCC*/ false);
}
@@ -264,7 +265,7 @@
// iterate over MI operands to find defs
for(MachineInstr::const_val_op_iterator DefI = MI->begin(),
DefE = MI->end(); DefI != DefE; ++DefI) {
- if (DefI.isDef()) { // iff this operand is a def
+ if (DefI.isDefOnly() || DefI.isDefAndUse()) { // this operand is modified
LiveRange *LROfDef = getLiveRangeForValue( *DefI );
RegClass *RCOfDef = LROfDef->getRegClass();
Index: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp
diff -u llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.94 llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.95
--- llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.94 Wed Jan 15 15:14:01 2003
+++ llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp Mon May 26 19:05:23 2003
@@ -302,7 +302,7 @@
//
for (MachineInstr::const_val_op_iterator OpI = MInst->begin(),
OpE = MInst->end(); OpI != OpE; ++OpI) {
- if (OpI.isDef()) // create a new LR iff this operand is a def
+ if (OpI.isDefOnly() || OpI.isDefAndUse()) // create a new LR since def
addInterference(*OpI, &LVSetAI, isCallInst);
// Calculate the spill cost of each live range
@@ -322,12 +322,10 @@
// instr (currently, only calls have this).
//
unsigned NumOfImpRefs = MInst->getNumImplicitRefs();
- if ( NumOfImpRefs > 0 ) {
- for (unsigned z=0; z < NumOfImpRefs; z++)
- if (MInst->implicitRefIsDefined(z) )
- addInterference( MInst->getImplicitRef(z), &LVSetAI, isCallInst );
- }
-
+ for (unsigned z=0; z < NumOfImpRefs; z++)
+ if (MInst->getImplicitOp(z).opIsDefOnly() ||
+ MInst->getImplicitOp(z).opIsDefAndUse())
+ addInterference( MInst->getImplicitRef(z), &LVSetAI, isCallInst );
} // for all machine instructions in BB
} // for all BBs in function
@@ -359,7 +357,7 @@
for (MachineInstr::const_val_op_iterator It1 = MInst->begin(),
ItE = MInst->end(); It1 != ItE; ++It1) {
const LiveRange *LROfOp1 = LRI.getLiveRangeForValue(*It1);
- assert((LROfOp1 || !It1.isDef()) && "No LR for Def in PSEUDO insruction");
+ assert((LROfOp1 || !It1.isUseOnly())&& "No LR for Def in PSEUDO insruction");
MachineInstr::const_val_op_iterator It2 = It1;
for (++It2; It2 != ItE; ++It2) {
@@ -652,8 +650,8 @@
"Return value of a ret must be handled elsewhere");
MachineOperand& Op = MInst->getOperand(OpNum);
- bool isDef = MInst->operandIsDefined(OpNum);
- bool isDefAndUse = MInst->operandIsDefinedAndUsed(OpNum);
+ bool isDef = Op.opIsDefOnly();
+ bool isDefAndUse = Op.opIsDefAndUse();
unsigned RegType = MRI.getRegType(LR);
int SpillOff = LR->getSpillOffFromFP();
RegClass *RC = LR->getRegClass();
@@ -885,8 +883,8 @@
{
const MachineOperand& Op = MInst->getOperand(OpNum);
- if (MInst->getOperandType(OpNum) == MachineOperand::MO_VirtualRegister ||
- MInst->getOperandType(OpNum) == MachineOperand::MO_CCRegister)
+ if (Op.getType() == MachineOperand::MO_VirtualRegister ||
+ Op.getType() == MachineOperand::MO_CCRegister)
if (const Value* Val = Op.getVRegValue())
if (MRI.getRegClassIDOfType(Val->getType()) == RC->getID())
if (Op.getAllocatedRegNum() == -1)
@@ -987,7 +985,7 @@
else
cerr << "(" << Val << ")";
- if (Op.opIsDef() )
+ if (Op.opIsDefOnly() || Op.opIsDefAndUse())
cerr << "*";
const LiveRange *LROfVal = LRI.getLiveRangeForValue(Val);
From vadve at cs.uiuc.edu Mon May 26 19:06:02 2003
From: vadve at cs.uiuc.edu (Vikram Adve)
Date: Mon May 26 19:06:02 2003
Subject: [llvm-commits] CVS: llvm/lib/CodeGen/InstrSched/SchedGraph.cpp
Message-ID: <200305270005.TAA31219@psmith.cs.uiuc.edu>
Changes in directory llvm/lib/CodeGen/InstrSched:
SchedGraph.cpp updated: 1.43 -> 1.44
---
Log message:
(1) Added special register class containing (for now) %fsr.
Fixed spilling of %fcc[0-3] which are part of %fsr.
(2) Moved some machine-independent reg-class code to class TargetRegInfo
from SparcReg{Class,}Info.
(3) Renamed MachienOperand::opIsDef to MachineOperand::opIsDefOnly()
and related functions and flags. Fixed several bugs where only
"isDef" was being checked, not "isDefAndUse".
---
Diffs of the changes:
Index: llvm/lib/CodeGen/InstrSched/SchedGraph.cpp
diff -u llvm/lib/CodeGen/InstrSched/SchedGraph.cpp:1.43 llvm/lib/CodeGen/InstrSched/SchedGraph.cpp:1.44
--- llvm/lib/CodeGen/InstrSched/SchedGraph.cpp:1.43 Thu May 22 16:49:18 2003
+++ llvm/lib/CodeGen/InstrSched/SchedGraph.cpp Mon May 26 19:05:20 2003
@@ -525,18 +525,18 @@
for (unsigned i=0; i < regRefVec.size(); ++i) {
SchedGraphNode* node = regRefVec[i].first;
unsigned int opNum = regRefVec[i].second;
- bool isDef = node->getMachineInstr()->operandIsDefined(opNum);
+ bool isDef = node->getMachineInstr()->getOperand(opNum).opIsDefOnly();
bool isDefAndUse =
- node->getMachineInstr()->operandIsDefinedAndUsed(opNum);
+ node->getMachineInstr()->getOperand(opNum).opIsDefAndUse();
for (unsigned p=0; p < i; ++p) {
SchedGraphNode* prevNode = regRefVec[p].first;
if (prevNode != node) {
unsigned int prevOpNum = regRefVec[p].second;
bool prevIsDef =
- prevNode->getMachineInstr()->operandIsDefined(prevOpNum);
+ prevNode->getMachineInstr()->getOperand(prevOpNum).opIsDefOnly();
bool prevIsDefAndUse =
- prevNode->getMachineInstr()->operandIsDefinedAndUsed(prevOpNum);
+ prevNode->getMachineInstr()->getOperand(prevOpNum).opIsDefAndUse();
if (isDef) {
if (prevIsDef)
new SchedGraphEdge(prevNode, node, regNum,
@@ -612,7 +612,7 @@
//
for (unsigned i = 0, numOps = MI.getNumOperands(); i != numOps; ++i)
{
- switch (MI.getOperandType(i))
+ switch (MI.getOperand(i).getType())
{
case MachineOperand::MO_VirtualRegister:
case MachineOperand::MO_CCRegister:
@@ -622,8 +622,8 @@
ValueToDefVecMap::const_iterator I = valueToDefVecMap.find(srcI);
if (I != valueToDefVecMap.end())
addEdgesForValue(node, I->second, srcI,
- MI.operandIsDefined(i),
- MI.operandIsDefinedAndUsed(i), target);
+ MI.getOperand(i).opIsDefOnly(),
+ MI.getOperand(i).opIsDefAndUse(), target);
}
break;
@@ -646,16 +646,15 @@
// value of a Ret instruction.
//
for (unsigned i=0, N=MI.getNumImplicitRefs(); i < N; ++i)
- if (! MI.implicitRefIsDefined(i) ||
- MI.implicitRefIsDefinedAndUsed(i))
+ if (MI.getImplicitOp(i).opIsUse() || MI.getImplicitOp(i).opIsDefAndUse())
if (const Instruction *srcI =
dyn_cast_or_null(MI.getImplicitRef(i)))
{
ValueToDefVecMap::const_iterator I = valueToDefVecMap.find(srcI);
if (I != valueToDefVecMap.end())
addEdgesForValue(node, I->second, srcI,
- MI.implicitRefIsDefined(i),
- MI.implicitRefIsDefinedAndUsed(i), target);
+ MI.getImplicitOp(i).opIsDefOnly(),
+ MI.getImplicitOp(i).opIsDefAndUse(), target);
}
}
@@ -693,7 +692,8 @@
}
// ignore all other non-def operands
- if (! minstr.operandIsDefined(i))
+ if (!minstr.getOperand(i).opIsDefOnly() &&
+ !minstr.getOperand(i).opIsDefAndUse())
continue;
// We must be defining a value.
@@ -710,7 +710,8 @@
// them assumes they must be virtual registers!
//
for (unsigned i=0, N = minstr.getNumImplicitRefs(); i != N; ++i)
- if (minstr.implicitRefIsDefined(i))
+ if (minstr.getImplicitOp(i).opIsDefOnly() ||
+ minstr.getImplicitOp(i).opIsDefAndUse())
if (const Instruction* defInstr =
dyn_cast_or_null(minstr.getImplicitRef(i)))
valueToDefVecMap[defInstr].push_back(std::make_pair(node, -i));
From vadve at cs.uiuc.edu Mon May 26 19:06:03 2003
From: vadve at cs.uiuc.edu (Vikram Adve)
Date: Mon May 26 19:06:03 2003
Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveVariables.cpp MachineInstr.cpp PHIElimination.cpp PrologEpilogInserter.cpp RegAllocLocal.cpp RegAllocSimple.cpp
Message-ID: <200305270005.TAA31211@psmith.cs.uiuc.edu>
Changes in directory llvm/lib/CodeGen:
LiveVariables.cpp updated: 1.7 -> 1.8
MachineInstr.cpp updated: 1.70 -> 1.71
PHIElimination.cpp updated: 1.8 -> 1.9
PrologEpilogInserter.cpp updated: 1.10 -> 1.11
RegAllocLocal.cpp updated: 1.15 -> 1.16
RegAllocSimple.cpp updated: 1.38 -> 1.39
---
Log message:
(1) Added special register class containing (for now) %fsr.
Fixed spilling of %fcc[0-3] which are part of %fsr.
(2) Moved some machine-independent reg-class code to class TargetRegInfo
from SparcReg{Class,}Info.
(3) Renamed MachienOperand::opIsDef to MachineOperand::opIsDefOnly()
and related functions and flags. Fixed several bugs where only
"isDef" was being checked, not "isDefAndUse".
---
Diffs of the changes:
Index: llvm/lib/CodeGen/LiveVariables.cpp
diff -u llvm/lib/CodeGen/LiveVariables.cpp:1.7 llvm/lib/CodeGen/LiveVariables.cpp:1.8
--- llvm/lib/CodeGen/LiveVariables.cpp:1.7 Mon May 12 09:24:00 2003
+++ llvm/lib/CodeGen/LiveVariables.cpp Mon May 26 19:05:17 2003
@@ -231,7 +231,7 @@
// Process all explicit defs...
for (unsigned i = 0; i != NumOperandsToProcess; ++i) {
MachineOperand &MO = MI->getOperand(i);
- if (MO.opIsDef() || MO.opIsDefAndUse()) {
+ if (MO.opIsDefOnly() || MO.opIsDefAndUse()) {
if (MO.isVirtualRegister()) {
VarInfo &VRInfo = getVarInfo(MO.getReg());
Index: llvm/lib/CodeGen/MachineInstr.cpp
diff -u llvm/lib/CodeGen/MachineInstr.cpp:1.70 llvm/lib/CodeGen/MachineInstr.cpp:1.71
--- llvm/lib/CodeGen/MachineInstr.cpp:1.70 Wed Jan 15 13:47:02 2003
+++ llvm/lib/CodeGen/MachineInstr.cpp Mon May 26 19:05:17 2003
@@ -94,7 +94,7 @@
if (isDefAndUse)
operands[i].flags = MachineOperand::DEFUSEFLAG;
else if (isdef || TargetInstrDescriptors[opCode].resultPos == (int) i)
- operands[i].flags = MachineOperand::DEFFLAG;
+ operands[i].flags = MachineOperand::DEFONLYFLAG;
else
operands[i].flags = 0;
}
@@ -126,7 +126,7 @@
operands[i].regNum = regNum;
if (isdef || TargetInstrDescriptors[opCode].resultPos == (int) i)
- operands[i].flags = MachineOperand::DEFFLAG;
+ operands[i].flags = MachineOperand::DEFONLYFLAG;
else
operands[i].flags = 0;
@@ -152,7 +152,7 @@
// Subsitute operands
for (MachineInstr::val_op_iterator O = begin(), E = end(); O != E; ++O)
if (*O == oldVal)
- if (!defsOnly || O.isDef())
+ if (!defsOnly || !O.isUseOnly())
{
O.getMachineOperand().value = newVal;
++numSubst;
@@ -161,7 +161,7 @@
// Subsitute implicit refs
for (unsigned i=0, N=getNumImplicitRefs(); i < N; ++i)
if (getImplicitRef(i) == oldVal)
- if (!defsOnly || implicitRefIsDefined(i))
+ if (!defsOnly || !getImplicitOp(i).opIsUse())
{
getImplicitOp(i).value = newVal;
++numSubst;
@@ -281,7 +281,8 @@
unsigned StartOp = 0;
// Specialize printing if op#0 is definition
- if (getNumOperands() && operandIsDefined(0)) {
+ if (getNumOperands() &&
+ (getOperand(0).opIsDefOnly() || getOperand(0).opIsDefAndUse())) {
::print(getOperand(0), OS, TM);
OS << " = ";
++StartOp; // Don't print this operand again!
@@ -289,14 +290,15 @@
OS << TM.getInstrInfo().getName(getOpcode());
for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) {
+ const MachineOperand& mop = getOperand(i);
if (i != StartOp)
OS << ",";
OS << " ";
- ::print(getOperand(i), OS, TM);
+ ::print(mop, OS, TM);
- if (operandIsDefinedAndUsed(i))
+ if (mop.opIsDefAndUse())
OS << "";
- else if (operandIsDefined(i))
+ else if (mop.opIsDefOnly())
OS << "";
}
@@ -305,10 +307,10 @@
OS << "\tImplicitRefs: ";
for(unsigned i = 0, e = getNumImplicitRefs(); i != e; ++i) {
OS << "\t";
- OutputValue(OS, getImplicitRef(i));
- if (implicitRefIsDefinedAndUsed(i))
+ OutputValue(OS, getImplicitRef(i));
+ if (getImplicitOp(i).opIsDefAndUse())
OS << "";
- else if (implicitRefIsDefined(i))
+ else if (getImplicitOp(i).opIsDefOnly())
OS << "";
}
}
@@ -323,9 +325,9 @@
for (unsigned i=0, N=MI.getNumOperands(); i < N; i++) {
os << "\t" << MI.getOperand(i);
- if (MI.operandIsDefined(i))
+ if (MI.getOperand(i).opIsDefOnly())
os << "";
- if (MI.operandIsDefinedAndUsed(i))
+ if (MI.getOperand(i).opIsDefAndUse())
os << "";
}
@@ -335,8 +337,8 @@
os << "\tImplicit: ";
for (unsigned z=0; z < NumOfImpRefs; z++) {
OutputValue(os, MI.getImplicitRef(z));
- if (MI.implicitRefIsDefined(z)) os << "";
- if (MI.implicitRefIsDefinedAndUsed(z)) os << "";
+ if (MI.getImplicitOp(z).opIsDefOnly()) os << "";
+ if (MI.getImplicitOp(z).opIsDefAndUse()) os << "";
os << "\t";
}
}
Index: llvm/lib/CodeGen/PHIElimination.cpp
diff -u llvm/lib/CodeGen/PHIElimination.cpp:1.8 llvm/lib/CodeGen/PHIElimination.cpp:1.9
--- llvm/lib/CodeGen/PHIElimination.cpp:1.8 Mon May 12 12:37:30 2003
+++ llvm/lib/CodeGen/PHIElimination.cpp Mon May 26 19:05:17 2003
@@ -165,7 +165,7 @@
for (unsigned i = 0, e = PrevInst->getNumOperands(); i != e; ++i) {
MachineOperand &MO = PrevInst->getOperand(i);
if (MO.isVirtualRegister() && MO.getReg() == IncomingReg)
- if (MO.opIsDef() || MO.opIsDefAndUse()) {
+ if (MO.opIsDefOnly() || MO.opIsDefAndUse()) {
HaveNotEmitted = false;
break;
}
Index: llvm/lib/CodeGen/PrologEpilogInserter.cpp
diff -u llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.10 llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.11
--- llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.10 Fri May 2 13:44:42 2003
+++ llvm/lib/CodeGen/PrologEpilogInserter.cpp Mon May 26 19:05:17 2003
@@ -108,7 +108,8 @@
MachineOperand &MO = (*I)->getOperand(i);
assert(!MO.isVirtualRegister() &&
"Register allocation must be performed!");
- if (MO.isPhysicalRegister() && MO.opIsDef())
+ if (MO.isPhysicalRegister() &&
+ (MO.opIsDefOnly() || MO.opIsDefAndUse()))
ModifiedRegs[MO.getReg()] = true; // Register is modified
}
++I;
Index: llvm/lib/CodeGen/RegAllocLocal.cpp
diff -u llvm/lib/CodeGen/RegAllocLocal.cpp:1.15 llvm/lib/CodeGen/RegAllocLocal.cpp:1.16
--- llvm/lib/CodeGen/RegAllocLocal.cpp:1.15 Sun May 11 22:54:14 2003
+++ llvm/lib/CodeGen/RegAllocLocal.cpp Mon May 26 19:05:17 2003
@@ -489,7 +489,7 @@
// Loop over all of the operands of the instruction, spilling registers that
// are defined, and marking explicit destinations in the PhysRegsUsed map.
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i)
- if ((MI->getOperand(i).opIsDef() || MI->getOperand(i).opIsDefAndUse()) &&
+ if ((MI->getOperand(i).opIsDefOnly() || MI->getOperand(i).opIsDefAndUse()) &&
MI->getOperand(i).isPhysicalRegister()) {
unsigned Reg = MI->getOperand(i).getAllocatedRegNum();
spillPhysReg(MBB, I, Reg); // Spill any existing value in the reg
@@ -512,8 +512,8 @@
// we need to scavenge a register.
//
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i)
- if (MI->getOperand(i).opIsDef() &&
- MI->getOperand(i).isVirtualRegister()) {
+ if ((MI->getOperand(i).opIsDefOnly() || MI->getOperand(i).opIsDefAndUse())
+ && MI->getOperand(i).isVirtualRegister()) {
unsigned DestVirtReg = MI->getOperand(i).getAllocatedRegNum();
unsigned DestPhysReg;
Index: llvm/lib/CodeGen/RegAllocSimple.cpp
diff -u llvm/lib/CodeGen/RegAllocSimple.cpp:1.38 llvm/lib/CodeGen/RegAllocSimple.cpp:1.39
--- llvm/lib/CodeGen/RegAllocSimple.cpp:1.38 Tue Jan 14 15:58:41 2003
+++ llvm/lib/CodeGen/RegAllocSimple.cpp Mon May 26 19:05:17 2003
@@ -173,7 +173,7 @@
// register in any given instruction
unsigned physReg = Virt2PhysRegMap[virtualReg];
if (physReg == 0) {
- if (op.opIsDef()) {
+ if (op.opIsDefOnly() || op.opIsDefAndUse()) {
if (TM->getInstrInfo().isTwoAddrInstr(MI->getOpcode()) && i == 0) {
// must be same register number as the first operand
// This maps a = b + c into b += c, and saves b into a's spot
From vadve at cs.uiuc.edu Mon May 26 19:07:00 2003
From: vadve at cs.uiuc.edu (Vikram Adve)
Date: Mon May 26 19:07:00 2003
Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineInstr.h
Message-ID: <200305270006.TAA31399@psmith.cs.uiuc.edu>
Changes in directory llvm/include/llvm/CodeGen:
MachineInstr.h updated: 1.98 -> 1.99
---
Log message:
Renamed MachienOperand::opIsDef to MachineOperand::opIsDefOnly()
and related functions and flags. Fixed several bugs where only
"isDef" was being checked, not "isDefAndUse".
---
Diffs of the changes:
Index: llvm/include/llvm/CodeGen/MachineInstr.h
diff -u llvm/include/llvm/CodeGen/MachineInstr.h:1.98 llvm/include/llvm/CodeGen/MachineInstr.h:1.99
--- llvm/include/llvm/CodeGen/MachineInstr.h:1.98 Wed Jan 15 13:46:51 2003
+++ llvm/include/llvm/CodeGen/MachineInstr.h Mon May 26 19:06:48 2003
@@ -88,13 +88,13 @@
private:
// Bit fields of the flags variable used for different operand properties
enum {
- DEFFLAG = 0x01, // this is a def of the operand
- DEFUSEFLAG = 0x02, // this is both a def and a use
- HIFLAG32 = 0x04, // operand is %hi32(value_or_immedVal)
- LOFLAG32 = 0x08, // operand is %lo32(value_or_immedVal)
- HIFLAG64 = 0x10, // operand is %hi64(value_or_immedVal)
- LOFLAG64 = 0x20, // operand is %lo64(value_or_immedVal)
- PCRELATIVE = 0x40, // Operand is relative to PC, not a global address
+ DEFONLYFLAG = 0x01, // this is a def but not a use of the operand
+ DEFUSEFLAG = 0x02, // this is both a def and a use
+ HIFLAG32 = 0x04, // operand is %hi32(value_or_immedVal)
+ LOFLAG32 = 0x08, // operand is %lo32(value_or_immedVal)
+ HIFLAG64 = 0x10, // operand is %hi64(value_or_immedVal)
+ LOFLAG64 = 0x20, // operand is %lo64(value_or_immedVal)
+ PCRELATIVE = 0x40, // Operand is relative to PC, not a global address
USEDEFMASK = 0x03,
};
@@ -137,7 +137,7 @@
regNum(Reg) {
switch (UseTy) {
case MOTy::Use: flags = 0; break;
- case MOTy::Def: flags = DEFFLAG; break;
+ case MOTy::Def: flags = DEFONLYFLAG; break;
case MOTy::UseAndDef: flags = DEFUSEFLAG; break;
default: assert(0 && "Invalid value for UseTy!");
}
@@ -148,7 +148,7 @@
: value(V), opType(OpTy), regNum(-1) {
switch (UseTy) {
case MOTy::Use: flags = 0; break;
- case MOTy::Def: flags = DEFFLAG; break;
+ case MOTy::Def: flags = DEFONLYFLAG; break;
case MOTy::UseAndDef: flags = DEFUSEFLAG; break;
default: assert(0 && "Invalid value for UseTy!");
}
@@ -259,7 +259,7 @@
}
bool opIsUse () const { return (flags & USEDEFMASK) == 0; }
- bool opIsDef () const { return flags & DEFFLAG; }
+ bool opIsDefOnly () const { return flags & DEFONLYFLAG; }
bool opIsDefAndUse () const { return flags & DEFUSEFLAG; }
bool opHiBits32 () const { return flags & HIFLAG32; }
bool opLoBits32 () const { return flags & LOFLAG32; }
@@ -332,15 +332,6 @@
std::vector operands; // the operands
unsigned numImplicitRefs; // number of implicit operands
- MachineOperand& getImplicitOp(unsigned i) {
- assert(i < numImplicitRefs && "implicit ref# out of range!");
- return operands[i + operands.size() - numImplicitRefs];
- }
- const MachineOperand& getImplicitOp(unsigned i) const {
- assert(i < numImplicitRefs && "implicit ref# out of range!");
- return operands[i + operands.size() - numImplicitRefs];
- }
-
// regsUsed - all machine registers used for this instruction, including regs
// used to save values across the instruction. This is a bitset of registers.
std::vector regsUsed;
@@ -371,7 +362,7 @@
const MachineOpCode getOpCode() const { return opCode; }
//
- // Information about explicit operands of the instruction
+ // Access to explicit operands of the instruction
//
unsigned getNumOperands() const { return operands.size() - numImplicitRefs; }
@@ -384,38 +375,27 @@
return operands[i];
}
- // FIXME: ELIMINATE
- MachineOperand::MachineOperandType getOperandType(unsigned i) const {
- return getOperand(i).getType();
- }
-
- // FIXME: ELIMINATE: Misleading name: Definition not defined.
- bool operandIsDefined(unsigned i) const {
- return getOperand(i).opIsDef();
- }
-
- bool operandIsDefinedAndUsed(unsigned i) const {
- return getOperand(i).opIsDefAndUse();
- }
-
//
- // Information about implicit operands of the instruction
+ // Access to implicit operands of the instruction
//
unsigned getNumImplicitRefs() const{ return numImplicitRefs; }
- const Value* getImplicitRef(unsigned i) const {
- return getImplicitOp(i).getVRegValue();
+ MachineOperand& getImplicitOp(unsigned i) {
+ assert(i < numImplicitRefs && "implicit ref# out of range!");
+ return operands[i + operands.size() - numImplicitRefs];
}
- Value* getImplicitRef(unsigned i) {
- return getImplicitOp(i).getVRegValue();
+ const MachineOperand& getImplicitOp(unsigned i) const {
+ assert(i < numImplicitRefs && "implicit ref# out of range!");
+ return operands[i + operands.size() - numImplicitRefs];
}
- bool implicitRefIsDefined(unsigned i) const {
- return getImplicitOp(i).opIsDef();
+ Value* getImplicitRef(unsigned i) {
+ return getImplicitOp(i).getVRegValue();
}
- bool implicitRefIsDefinedAndUsed(unsigned i) const {
- return getImplicitOp(i).opIsDefAndUse();
+ const Value* getImplicitRef(unsigned i) const {
+ return getImplicitOp(i).getVRegValue();
}
+
inline void addImplicitRef (Value* V,
bool isDef=false,bool isDefAndUse=false);
inline void setImplicitRef (unsigned i, Value* V,
@@ -647,8 +627,8 @@
void skipToNextVal() {
while (i < MI->getNumOperands() &&
- !( (MI->getOperandType(i) == MachineOperand::MO_VirtualRegister ||
- MI->getOperandType(i) == MachineOperand::MO_CCRegister)
+ !( (MI->getOperand(i).getType() == MachineOperand::MO_VirtualRegister ||
+ MI->getOperand(i).getType() == MachineOperand::MO_CCRegister)
&& MI->getOperand(i).getVRegValue() != 0))
++i;
}
@@ -669,7 +649,8 @@
inline VTy operator->() const { return operator*(); }
- inline bool isDef() const { return MI->getOperand(i).opIsDef(); }
+ inline bool isUseOnly() const { return MI->getOperand(i).opIsUse(); }
+ inline bool isDefOnly() const { return MI->getOperand(i).opIsDefOnly(); }
inline bool isDefAndUse() const { return MI->getOperand(i).opIsDefAndUse();}
inline _Self& operator++() { i++; skipToNextVal(); return *this; }
From vadve at cs.uiuc.edu Mon May 26 19:07:01 2003
From: vadve at cs.uiuc.edu (Vikram Adve)
Date: Mon May 26 19:07:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Analysis/LiveVar/BBLiveVar.cpp FunctionLiveVarInfo.cpp
Message-ID: <200305270006.TAA31369@psmith.cs.uiuc.edu>
Changes in directory llvm/lib/Analysis/LiveVar:
BBLiveVar.cpp updated: 1.34 -> 1.35
FunctionLiveVarInfo.cpp updated: 1.42 -> 1.43
---
Log message:
Renamed MachienOperand::opIsDef to MachineOperand::opIsDefOnly()
and related functions and flags. Fixed several bugs where only
"isDef" was being checked, not "isDefAndUse".
---
Diffs of the changes:
Index: llvm/lib/Analysis/LiveVar/BBLiveVar.cpp
diff -u llvm/lib/Analysis/LiveVar/BBLiveVar.cpp:1.34 llvm/lib/Analysis/LiveVar/BBLiveVar.cpp:1.35
--- llvm/lib/Analysis/LiveVar/BBLiveVar.cpp:1.34 Tue May 20 15:36:39 2003
+++ llvm/lib/Analysis/LiveVar/BBLiveVar.cpp Mon May 26 19:06:00 2003
@@ -64,12 +64,12 @@
// iterate over MI operands to find defs
for (MachineInstr::const_val_op_iterator OpI = MI->begin(), OpE = MI->end();
OpI != OpE; ++OpI)
- if (OpI.isDef()) // add to Defs only if this operand is a def
+ if (OpI.isDefOnly() || OpI.isDefAndUse()) // add to Defs if this operand is a def
addDef(*OpI);
// do for implicit operands as well
for (unsigned i = 0; i < MI->getNumImplicitRefs(); ++i)
- if (MI->implicitRefIsDefined(i))
+ if (MI->getImplicitOp(i).opIsDefOnly() || MI->getImplicitOp(i).opIsDefAndUse())
addDef(MI->getImplicitRef(i));
// iterate over MI operands to find uses
@@ -80,7 +80,7 @@
if (isa(Op))
continue; // don't process labels
- if (!OpI.isDef() || OpI.isDefAndUse()) {
+ if (OpI.isUseOnly() || OpI.isDefAndUse()) {
// add to Uses only if this operand is a use
//
// *** WARNING: The following code for handling dummy PHI machine
@@ -116,7 +116,7 @@
if (Op->getType() == Type::LabelTy) // don't process labels
continue;
- if (!MI->implicitRefIsDefined(i) || MI->implicitRefIsDefinedAndUsed(i) )
+ if (MI->getImplicitOp(i).opIsUse() || MI->getImplicitOp(i).opIsDefAndUse())
addUse(Op);
}
} // for all machine instructions
Index: llvm/lib/Analysis/LiveVar/FunctionLiveVarInfo.cpp
diff -u llvm/lib/Analysis/LiveVar/FunctionLiveVarInfo.cpp:1.42 llvm/lib/Analysis/LiveVar/FunctionLiveVarInfo.cpp:1.43
--- llvm/lib/Analysis/LiveVar/FunctionLiveVarInfo.cpp:1.42 Tue Jan 14 17:05:00 2003
+++ llvm/lib/Analysis/LiveVar/FunctionLiveVarInfo.cpp Mon May 26 19:06:00 2003
@@ -213,13 +213,14 @@
static void applyTranferFuncForMInst(ValueSet &LVS, const MachineInstr *MInst) {
for (MachineInstr::const_val_op_iterator OpI = MInst->begin(),
OpE = MInst->end(); OpI != OpE; ++OpI) {
- if (OpI.isDef()) // kill only if this operand is a def
- LVS.erase(*OpI); // this definition kills any uses
+ if (OpI.isDefOnly() || OpI.isDefAndUse()) // kill if this operand is a def
+ LVS.erase(*OpI); // this definition kills any uses
}
// do for implicit operands as well
for (unsigned i=0; i < MInst->getNumImplicitRefs(); ++i) {
- if (MInst->implicitRefIsDefined(i))
+ if (MInst->getImplicitOp(i).opIsDefOnly() ||
+ MInst->getImplicitOp(i).opIsDefAndUse())
LVS.erase(MInst->getImplicitRef(i));
}
@@ -227,14 +228,14 @@
OpE = MInst->end(); OpI != OpE; ++OpI) {
if (!isa(*OpI)) // don't process labels
// add only if this operand is a use
- if (!OpI.isDef() || OpI.isDefAndUse() )
+ if (!OpI.isDefOnly() || OpI.isDefAndUse() )
LVS.insert(*OpI); // An operand is a use - so add to use set
}
// do for implicit operands as well
for (unsigned i = 0, e = MInst->getNumImplicitRefs(); i != e; ++i)
- if (!MInst->implicitRefIsDefined(i) ||
- MInst->implicitRefIsDefinedAndUsed(i))
+ if (MInst->getImplicitOp(i).opIsUse() ||
+ MInst->getImplicitOp(i).opIsDefAndUse())
LVS.insert(MInst->getImplicitRef(i));
}
From vadve at cs.uiuc.edu Mon May 26 19:08:01 2003
From: vadve at cs.uiuc.edu (Vikram Adve)
Date: Mon May 26 19:08:01 2003
Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetRegInfo.h
Message-ID: <200305270007.TAA31473@psmith.cs.uiuc.edu>
Changes in directory llvm/include/llvm/Target:
TargetRegInfo.h updated: 1.33 -> 1.34
---
Log message:
(1) Added special register class containing (for now) %fsr.
Fixed spilling of %fcc[0-3] which are part of %fsr.
(2) Moved some machine-independent reg-class code to class TargetRegInfo
from SparcReg{Class,}Info.
---
Diffs of the changes:
Index: llvm/include/llvm/Target/TargetRegInfo.h
diff -u llvm/include/llvm/Target/TargetRegInfo.h:1.33 llvm/include/llvm/Target/TargetRegInfo.h:1.34
--- llvm/include/llvm/Target/TargetRegInfo.h:1.33 Sun May 25 11:02:05 2003
+++ llvm/include/llvm/Target/TargetRegInfo.h Mon May 26 19:07:13 2003
@@ -45,6 +45,8 @@
std::vector &IsColorUsedArr) const = 0;
virtual bool isRegVolatile(int Reg) const = 0;
+ virtual const char* const getRegName(unsigned reg) const = 0;
+
TargetRegClassInfo(unsigned ID, unsigned NVR, unsigned NAR)
: RegClassID(ID), NumOfAvailRegs(NVR), NumOfAllRegs(NAR) {}
};
@@ -75,11 +77,16 @@
// code register class will be returned. Otherwise, the normal register
// class (eg. int, float) must be returned.
virtual unsigned getRegClassIDOfType (const Type *type,
- bool isCCReg = false) const =0;
- virtual unsigned getRegClassIDOfReg (int unifiedRegNum) const =0;
- virtual unsigned getRegClassIDOfRegType(int regType) const =0;
-
- inline unsigned int getNumOfRegClasses() const {
+ bool isCCReg = false) const = 0;
+ virtual unsigned getRegClassIDOfRegType(int regType) const = 0;
+
+ unsigned getRegClassIDOfReg(int unifiedRegNum) const {
+ unsigned classId = 0;
+ (void) getClassRegNum(unifiedRegNum, classId);
+ return classId;
+ }
+
+ unsigned int getNumOfRegClasses() const {
return MachineRegClassArr.size();
}
@@ -169,13 +176,43 @@
// Each register class has a seperate space for register IDs. To convert
// a regId in a register class to a common Id, or vice versa,
- // we use the folloing methods.
+ // we use the folloing two methods.
//
- virtual int getUnifiedRegNum(unsigned regClassID, int reg) const = 0;
- virtual int getClassRegNum(int unifiedRegNum, unsigned& regClassID) const =0;
+ // Thsi method converts from class reg. number to unified register number.
+ int getUnifiedRegNum(unsigned regClassID, int reg) const {
+ if (reg == getInvalidRegNum()) { return getInvalidRegNum(); }
+ assert(regClassID < getNumOfRegClasses() && "Invalid register class");
+ int totalRegs = 0;
+ for (unsigned rcid = 0; rcid < regClassID; ++rcid)
+ totalRegs += MachineRegClassArr[rcid]->getNumOfAllRegs();
+ return reg + totalRegs;
+ }
+
+ // This method converts the unified number to the number in its class,
+ // and returns the class ID in regClassID.
+ int getClassRegNum(int uRegNum, unsigned& regClassID) const {
+ if (uRegNum == getInvalidRegNum()) { return getInvalidRegNum(); }
+
+ int totalRegs = 0, rcid = 0, NC = getNumOfRegClasses();
+ while (rcid < NC &&
+ uRegNum >= totalRegs + (int) MachineRegClassArr[rcid]->getNumOfAllRegs()) {
+ totalRegs += MachineRegClassArr[rcid]->getNumOfAllRegs();
+ rcid++;
+ }
+ if (rcid == NC) {
+ assert(0 && "getClassRegNum(): Invalid register number");
+ return getInvalidRegNum();
+ }
+ regClassID = rcid;
+ return uRegNum - totalRegs;
+ }
// Returns the assembly-language name of the specified machine register.
- virtual const char * const getUnifiedRegName(int UnifiedRegNum) const = 0;
+ const char * const getUnifiedRegName(int UnifiedRegNum) const {
+ unsigned regClassID = getNumOfRegClasses(); // initialize to invalid value
+ int regNumInClass = getClassRegNum(UnifiedRegNum, regClassID);
+ return MachineRegClassArr[regClassID]->getRegName(regNumInClass);
+ }
virtual int getRegType(const Type* type) const = 0;
virtual int getRegType(const LiveRange *LR) const = 0;
@@ -190,7 +227,6 @@
// be obtained using this method.
//
virtual int getInvalidRegNum() const = 0;
-
// Method for inserting caller saving code. The caller must save all the
// volatile registers across a call based on the calling conventions of
From lattner at cs.uiuc.edu Tue May 27 09:10:02 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Tue May 27 09:10:02 2003
Subject: [llvm-commits] CVS: llvm/test/Programs/SingleSource/UnitTests/2003-05-07-VarArgs.c
Message-ID: <200305271409.JAA30370@apoc.cs.uiuc.edu>
Changes in directory llvm/test/Programs/SingleSource/UnitTests:
2003-05-07-VarArgs.c updated: 1.5 -> 1.6
---
Log message:
Revert the last revision which is stopping the nightly tester. :(
---
Diffs of the changes:
Index: llvm/test/Programs/SingleSource/UnitTests/2003-05-07-VarArgs.c
diff -u llvm/test/Programs/SingleSource/UnitTests/2003-05-07-VarArgs.c:1.5 llvm/test/Programs/SingleSource/UnitTests/2003-05-07-VarArgs.c:1.6
--- llvm/test/Programs/SingleSource/UnitTests/2003-05-07-VarArgs.c:1.5 Sun May 25 11:30:15 2003
+++ llvm/test/Programs/SingleSource/UnitTests/2003-05-07-VarArgs.c Tue May 27 09:09:04 2003
@@ -1,7 +1,7 @@
#include
#include
-/* 8 bytes if alignon(int) is 4. */
+/* 5 bytes. */
typedef struct DWordS_struct { int i; char c; } DWordS;
/* 12 bytes if d is 4-byte aligned; 16 bytes if d is 8-byte aligned. */
@@ -47,17 +47,17 @@
printf("char %c\n", c);
break;
case 'D':
- dw = va_arg(ap, DWordS);
+ /* dw = va_arg(ap, DWordS);
printf("DWord { %d, %c }\n", dw.i, dw.c);
- break;
+ */ break;
case 'Q':
- qw = va_arg(ap, QuadWordS);
+ /* qw = va_arg(ap, QuadWordS);
printf("QuadWord { %d, %f }\n", qw.i, qw.d);
- break;
+ */ break;
case 'L':
- ls = va_arg(ap, LargeS);
+ /* ls = va_arg(ap, LargeS);
printf("LargeS { %d, %f, 0x%p, %d }\n", ls.i, ls.d, ls.ptr, ls.j);
- break;
+ */ break;
}
va_end(ap);
}
From lattner at cs.uiuc.edu Tue May 27 09:16:01 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Tue May 27 09:16:01 2003
Subject: [llvm-commits] CVS: llvm/test/Programs/SingleSource/mandel.c
Message-ID: <200305271415.JAA30434@apoc.cs.uiuc.edu>
Changes in directory llvm/test/Programs/SingleSource:
mandel.c added (r1.1)
---
Log message:
Simple test for C99 complex numbers
---
Diffs of the changes:
Index: llvm/test/Programs/SingleSource/mandel.c
diff -c /dev/null llvm/test/Programs/SingleSource/mandel.c:1.1
*** /dev/null Tue May 27 09:15:40 2003
--- llvm/test/Programs/SingleSource/mandel.c Tue May 27 09:15:30 2003
***************
*** 0 ****
--- 1,32 ----
+ #include
+ #define ESCAPE 2
+ #define IMAGE_SIZE 10
+ #define START_X -2.0
+ #define START_Y START_X
+ #define MAX_ITER 10
+ #define step (-START_X - START_X)/IMAGE_SIZE
+ void emit(double complex X) {
+ printf("%f\n", (double)X);
+ }
+
+ void mandel() {
+ int x, y, n;
+ for (x = 0; x < IMAGE_SIZE; ++x) {
+ for (y = 0; y < IMAGE_SIZE; ++y) {
+ double complex c = (START_X+x*step) + (START_Y-y*step) * I;
+ double complex z = 0.0;
+
+ for (n = 0; n < MAX_ITER; ++n) {
+ z = z * z + c;
+ if (cabs(z) >= ESCAPE)
+ break;
+ }
+ emit(z);
+ }
+ }
+ }
+
+ int main() {
+ mandel();
+ return 0;
+ }
From lattner at cs.uiuc.edu Tue May 27 10:46:05 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Tue May 27 10:46:05 2003
Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp
Message-ID: <200305271545.KAA30848@apoc.cs.uiuc.edu>
Changes in directory llvm/lib/Transforms/Scalar:
ScalarReplAggregates.cpp added (r1.1)
---
Log message:
Implementation of the simple "scalar replacement of aggregates" transformation
---
Diffs of the changes:
Index: llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp
diff -c /dev/null llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.1
*** /dev/null Tue May 27 10:45:37 2003
--- llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp Tue May 27 10:45:27 2003
***************
*** 0 ****
--- 1,164 ----
+ //===- ScalarReplAggregates.cpp - Scalar Replacement of Aggregates --------===//
+ //
+ // This transformation implements the well known scalar replacement of
+ // aggregates transformation. This xform breaks up alloca instructions of
+ // aggregate type (structure or array) into individual alloca instructions for
+ // each member (if possible).
+ //
+ //===----------------------------------------------------------------------===//
+
+ #include "llvm/Transforms/Scalar.h"
+ #include "llvm/Function.h"
+ #include "llvm/Pass.h"
+ #include "llvm/iMemory.h"
+ #include "llvm/DerivedTypes.h"
+ #include "llvm/Constants.h"
+ #include "Support/StringExtras.h"
+ #include "Support/Statistic.h"
+
+ namespace {
+ Statistic<> NumReplaced("scalarrepl", "Number of alloca's broken up");
+
+ struct SROA : public FunctionPass {
+ bool runOnFunction(Function &F);
+
+ private:
+ AllocaInst *AddNewAlloca(Function &F, const Type *Ty, AllocationInst *Base);
+ };
+
+ RegisterOpt X("scalarrepl", "Scalar Replacement of Aggregates");
+ }
+
+ Pass *createScalarReplAggregatesPass() { return new SROA(); }
+
+
+ // runOnFunction - This algorithm is a simple worklist driven algorithm, which
+ // runs on all of the malloc/alloca instructions in the function, removing them
+ // if they are only used by getelementptr instructions.
+ //
+ bool SROA::runOnFunction(Function &F) {
+ std::vector WorkList;
+
+ // Scan the entry basic block, adding any alloca's and mallocs to the worklist
+ BasicBlock &BB = F.getEntryNode();
+ for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I)
+ if (AllocationInst *A = dyn_cast(I))
+ WorkList.push_back(A);
+
+ // Process the worklist
+ bool Changed = false;
+ while (!WorkList.empty()) {
+ AllocationInst *AI = WorkList.back();
+ WorkList.pop_back();
+
+ // We cannot transform the allocation instruction if it is an array
+ // allocation, and an allocation of a scalar value cannot be decomposed
+ if (AI->isArrayAllocation() ||
+ (!isa(AI->getAllocatedType()) /*&&
+ !isa(AI->getAllocatedType())*/
+ )) continue;
+
+ // Loop over the use list of the alloca. We can only transform it if there
+ // are only getelementptr instructions (with a zero first index) and free
+ // instructions.
+ //
+ bool CannotTransform = false;
+ for (Value::use_iterator I = AI->use_begin(), E = AI->use_end();
+ I != E; ++I) {
+ Instruction *User = cast(*I);
+ if (GetElementPtrInst *GEPI = dyn_cast(User)) {
+ // The GEP is safe to transform if it is of the form GEP , 0,
+ if (GEPI->getNumOperands() <= 2 ||
+ GEPI->getOperand(1) != Constant::getNullValue(Type::LongTy) ||
+ !isa(GEPI->getOperand(2)) ||
+ isa(GEPI->getOperand(2))) {
+ DEBUG(std::cerr << "Cannot transform: " << *AI << " due to user: "
+ << User);
+ CannotTransform = true;
+ break;
+ }
+ } else {
+ DEBUG(std::cerr << "Cannot transform: " << *AI << " due to user: "
+ << User);
+ CannotTransform = true;
+ break;
+ }
+ }
+
+ if (CannotTransform) continue;
+
+ DEBUG(std::cerr << "Found inst to xform: " << *AI);
+ Changed = true;
+
+ std::vector ElementAllocas;
+ if (const StructType *ST = dyn_cast(AI->getAllocatedType())) {
+ ElementAllocas.reserve(ST->getNumContainedTypes());
+ for (unsigned i = 0, e = ST->getNumContainedTypes(); i != e; ++i) {
+ AllocaInst *NA = new AllocaInst(ST->getContainedType(i), 0,
+ AI->getName() + "." + utostr(i), AI);
+ ElementAllocas.push_back(NA);
+ WorkList.push_back(NA); // Add to worklist for recursive processing
+ }
+ } else {
+ const ArrayType *AT = cast(AI->getAllocatedType());
+ ElementAllocas.reserve(AT->getNumElements());
+ const Type *ElTy = AT->getElementType();
+ for (unsigned i = 0, e = AT->getNumElements(); i != e; ++i) {
+ AllocaInst *NA = new AllocaInst(ElTy, 0,
+ AI->getName() + "." + utostr(i), AI);
+ ElementAllocas.push_back(NA);
+ WorkList.push_back(NA); // Add to worklist for recursive processing
+ }
+ }
+
+ // Now that we have created the alloca instructions that we want to use,
+ // expand the getelementptr instructions to use them.
+ //
+ for (Value::use_iterator I = AI->use_begin(), E = AI->use_end();
+ I != E; ++I) {
+ Instruction *User = cast(*I);
+ if (GetElementPtrInst *GEPI = dyn_cast(User)) {
+ // We now know that the GEP is of the form: GEP , 0,
+ uint64_t Idx;
+ if (ConstantSInt *CSI = dyn_cast(GEPI->getOperand(2)))
+ Idx = CSI->getValue();
+ else
+ Idx = cast(GEPI->getOperand(2))->getValue();
+
+ assert(Idx < ElementAllocas.size() && "Index out of range?");
+ AllocaInst *AllocaToUse = ElementAllocas[Idx];
+
+ Value *RepValue;
+ if (GEPI->getNumOperands() == 3) {
+ // Do not insert a new getelementptr instruction with zero indices,
+ // only to have it optimized out later.
+ RepValue = AllocaToUse;
+ } else {
+ // We are indexing deeply into the structure, so we still need a
+ // getelement ptr instruction to finish the indexing. This may be
+ // expanded itself once the worklist is rerun.
+ //
+ std::string OldName = GEPI->getName(); // Steal the old name...
+ GEPI->setName("");
+ RepValue =
+ new GetElementPtrInst(AllocaToUse,
+ std::vector(GEPI->op_begin()+3,
+ GEPI->op_end()),
+ OldName, GEPI);
+ }
+
+ // Move all of the users over to the new GEP.
+ GEPI->replaceAllUsesWith(RepValue);
+ // Delete the old GEP
+ GEPI->getParent()->getInstList().erase(GEPI);
+ } else {
+ assert(0 && "Unexpected instruction type!");
+ }
+ }
+
+ // Finally, delete the Alloca instruction
+ AI->getParent()->getInstList().erase(AI);
+ }
+
+ return Changed;
+ }
From lattner at cs.uiuc.edu Tue May 27 10:48:02 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Tue May 27 10:48:02 2003
Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/ScalarRepl/
Message-ID: <200305271547.KAA30876@apoc.cs.uiuc.edu>
Changes in directory llvm/test/Regression/Transforms/ScalarRepl:
---
Log message:
Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/test/Regression/Transforms/ScalarRepl added to the repository
---
Diffs of the changes:
From lattner at cs.uiuc.edu Tue May 27 10:52:01 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Tue May 27 10:52:01 2003
Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/ScalarRepl/Makefile arraytest.ll badarray.ll basictest.ll
Message-ID: <200305271551.KAA30980@apoc.cs.uiuc.edu>
Changes in directory llvm/test/Regression/Transforms/ScalarRepl:
Makefile added (r1.1)
arraytest.ll added (r1.1)
badarray.ll added (r1.1)
basictest.ll added (r1.1)
---
Log message:
Initial testcases for scalar replacement of aggregates pass
---
Diffs of the changes:
Index: llvm/test/Regression/Transforms/ScalarRepl/Makefile
diff -c /dev/null llvm/test/Regression/Transforms/ScalarRepl/Makefile:1.1
*** /dev/null Tue May 27 10:51:27 2003
--- llvm/test/Regression/Transforms/ScalarRepl/Makefile Tue May 27 10:51:17 2003
***************
*** 0 ****
--- 1,10 ----
+
+ LEVEL = ../../../..
+ include $(LEVEL)/test/Makefile.tests
+
+ TESTS := $(wildcard *.ll)
+
+ all:: $(addprefix Output/, $(TESTS:%.ll=%.ll.out))
+
+ Output/%.ll.out: %.ll Output/.dir $(LOPT)
+ -$(TESTRUNR) $<
Index: llvm/test/Regression/Transforms/ScalarRepl/arraytest.ll
diff -c /dev/null llvm/test/Regression/Transforms/ScalarRepl/arraytest.ll:1.1
*** /dev/null Tue May 27 10:51:27 2003
--- llvm/test/Regression/Transforms/ScalarRepl/arraytest.ll Tue May 27 10:51:17 2003
***************
*** 0 ****
--- 1,13 ----
+ ; RUN: if as < %s | opt -scalarrepl -mem2reg | dis | grep alloca
+ ; RUN: then exit 1
+ ; RUN: else exit 0
+ ; RUN: fi
+
+ int %test() {
+ %X = alloca [ 4 x int ]
+ %Y = getelementptr [4x int]* %X, long 0, long 0
+ store int 0, int* %Y
+
+ %Z = load int* %Y
+ ret int %Z
+ }
Index: llvm/test/Regression/Transforms/ScalarRepl/badarray.ll
diff -c /dev/null llvm/test/Regression/Transforms/ScalarRepl/badarray.ll:1.1
*** /dev/null Tue May 27 10:51:27 2003
--- llvm/test/Regression/Transforms/ScalarRepl/badarray.ll Tue May 27 10:51:17 2003
***************
*** 0 ****
--- 1,10 ----
+ ; RUN: as < %s | opt -scalarrepl -mem2reg | dis | grep alloca
+
+ int %test() {
+ %X = alloca [ 4 x int ]
+ %Y = getelementptr [4x int]* %X, long 0, long 6 ; Off end of array!
+ store int 0, int* %Y
+
+ %Z = load int* %Y
+ ret int %Z
+ }
Index: llvm/test/Regression/Transforms/ScalarRepl/basictest.ll
diff -c /dev/null llvm/test/Regression/Transforms/ScalarRepl/basictest.ll:1.1
*** /dev/null Tue May 27 10:51:27 2003
--- llvm/test/Regression/Transforms/ScalarRepl/basictest.ll Tue May 27 10:51:17 2003
***************
*** 0 ****
--- 1,13 ----
+ ; RUN: if as < %s | opt -scalarrepl -mem2reg | dis | grep alloca
+ ; RUN: then exit 1
+ ; RUN: else exit 0
+ ; RUN: fi
+
+ int %test() {
+ %X = alloca { int, float }
+ %Y = getelementptr {int,float}* %X, long 0, ubyte 0
+ store int 0, int* %Y
+
+ %Z = load int* %Y
+ ret int %Z
+ }
From lattner at cs.uiuc.edu Tue May 27 10:53:00 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Tue May 27 10:53:00 2003
Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/Scalar.h
Message-ID: <200305271552.KAA31051@apoc.cs.uiuc.edu>
Changes in directory llvm/include/llvm/Transforms:
Scalar.h updated: 1.16 -> 1.17
---
Log message:
Expose proto for SRoA pass.
---
Diffs of the changes:
Index: llvm/include/llvm/Transforms/Scalar.h
diff -u llvm/include/llvm/Transforms/Scalar.h:1.16 llvm/include/llvm/Transforms/Scalar.h:1.17
--- llvm/include/llvm/Transforms/Scalar.h:1.16 Tue May 20 16:01:09 2003
+++ llvm/include/llvm/Transforms/Scalar.h Tue May 27 10:52:45 2003
@@ -56,6 +56,13 @@
//===----------------------------------------------------------------------===//
+//
+// Scalar Replacement of Aggregates - Break up alloca's of aggregates into
+// multiple allocas if possible.
+//
+Pass *createScalarReplAggregatesPass();
+
+//===----------------------------------------------------------------------===//
//
// DecomposeMultiDimRefs - Convert multi-dimensional references consisting of
// any combination of 2 or more array and structure indices into a sequence of
From lattner at cs.uiuc.edu Tue May 27 11:10:05 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Tue May 27 11:10:05 2003
Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp
Message-ID: <200305271609.LAA31125@apoc.cs.uiuc.edu>
Changes in directory llvm/lib/Transforms/Scalar:
ScalarReplAggregates.cpp updated: 1.1 -> 1.2
---
Log message:
* Actually USE the statistic that we made
* Implement SRoA for arrays
---
Diffs of the changes:
Index: llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp
diff -u llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.1 llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.2
--- llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.1 Tue May 27 10:45:27 2003
+++ llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp Tue May 27 11:09:27 2003
@@ -52,12 +52,15 @@
WorkList.pop_back();
// We cannot transform the allocation instruction if it is an array
- // allocation, and an allocation of a scalar value cannot be decomposed
+ // allocation (allocations OF arrays are ok though), and an allocation of a
+ // scalar value cannot be decomposed at all.
+ //
if (AI->isArrayAllocation() ||
- (!isa(AI->getAllocatedType()) /*&&
- !isa(AI->getAllocatedType())*/
- )) continue;
-
+ (!isa(AI->getAllocatedType()) &&
+ !isa(AI->getAllocatedType()))) continue;
+
+ const ArrayType *AT = dyn_cast(AI->getAllocatedType());
+
// Loop over the use list of the alloca. We can only transform it if there
// are only getelementptr instructions (with a zero first index) and free
// instructions.
@@ -77,6 +80,18 @@
CannotTransform = true;
break;
}
+
+ // If this is an array access, check to make sure that index falls
+ // within the array. If not, something funny is going on, so we won't
+ // do the optimization.
+ if (AT && cast(GEPI->getOperand(2))->getValue() >=
+ AT->getNumElements()) {
+ DEBUG(std::cerr << "Cannot transform: " << *AI << " due to user: "
+ << User);
+ CannotTransform = true;
+ break;
+ }
+
} else {
DEBUG(std::cerr << "Cannot transform: " << *AI << " due to user: "
<< User);
@@ -100,7 +115,6 @@
WorkList.push_back(NA); // Add to worklist for recursive processing
}
} else {
- const ArrayType *AT = cast(AI->getAllocatedType());
ElementAllocas.reserve(AT->getNumElements());
const Type *ElTy = AT->getElementType();
for (unsigned i = 0, e = AT->getNumElements(); i != e; ++i) {
@@ -158,6 +172,7 @@
// Finally, delete the Alloca instruction
AI->getParent()->getInstList().erase(AI);
+ NumReplaced++;
}
return Changed;
From lattner at cs.uiuc.edu Tue May 27 11:11:05 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Tue May 27 11:11:05 2003
Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/Makefile
Message-ID: <200305271610.LAA31160@apoc.cs.uiuc.edu>
Changes in directory llvm/test/Regression/Transforms:
Makefile updated: 1.22 -> 1.23
---
Log message:
Start testing SRoA
---
Diffs of the changes:
Index: llvm/test/Regression/Transforms/Makefile
diff -u llvm/test/Regression/Transforms/Makefile:1.22 llvm/test/Regression/Transforms/Makefile:1.23
--- llvm/test/Regression/Transforms/Makefile:1.22 Tue May 6 14:04:02 2003
+++ llvm/test/Regression/Transforms/Makefile Tue May 27 11:10:03 2003
@@ -22,6 +22,7 @@
ProfilePaths \
Reassociate \
SCCP \
+ ScalarRepl \
SimplifyCFG
include $(LEVEL)/Makefile.common
From lattner at cs.uiuc.edu Tue May 27 11:26:01 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Tue May 27 11:26:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Support/Signals.cpp
Message-ID: <200305271625.LAA31273@apoc.cs.uiuc.edu>
Changes in directory llvm/lib/Support:
Signals.cpp updated: 1.4 -> 1.5
---
Log message:
Make _sure_ we don't go into an infinite loop if a signal happens!
---
Diffs of the changes:
Index: llvm/lib/Support/Signals.cpp
diff -u llvm/lib/Support/Signals.cpp:1.4 llvm/lib/Support/Signals.cpp:1.5
--- llvm/lib/Support/Signals.cpp:1.4 Thu May 22 16:59:35 2003
+++ llvm/lib/Support/Signals.cpp Tue May 27 11:25:04 2003
@@ -42,6 +42,7 @@
exit(1); // If this is an interrupt signal, exit the program
// Otherwise if it is a fault (like SEGV) reissue the signal to die...
+ signal(Sig, SIG_DFL);
}
static void RegisterHandler(int Signal) { signal(Signal, SignalHandler); }
From lattner at cs.uiuc.edu Tue May 27 11:42:01 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Tue May 27 11:42:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Message-ID: <200305271641.LAA31340@apoc.cs.uiuc.edu>
Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.84 -> 1.85
---
Log message:
Fix bug: Instcombine/2003-05-27-ConstExprCrash.ll
---
Diffs of the changes:
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.84 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.85
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.84 Mon May 26 18:41:32 2003
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Tue May 27 11:40:51 2003
@@ -17,9 +17,10 @@
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
-#include "llvm/ConstantHandling.h"
#include "llvm/Instructions.h"
#include "llvm/Pass.h"
+#include "llvm/Constants.h"
+#include "llvm/ConstantHandling.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Support/InstIterator.h"
#include "llvm/Support/InstVisitor.h"
@@ -149,9 +150,9 @@
if (BinaryOperator *Op = dyn_cast(I.getOperand(0)))
if (Op->getOpcode() == Opcode && isa(Op->getOperand(1))) {
if (isa(I.getOperand(1))) {
- Constant *Folded = ConstantFoldBinaryInstruction(I.getOpcode(),
- cast(I.getOperand(1)), cast(Op->getOperand(1)));
- assert(Folded && "Couldn't constant fold commutative operand?");
+ Constant *Folded = ConstantExpr::get(I.getOpcode(),
+ cast(I.getOperand(1)),
+ cast(Op->getOperand(1)));
I.setOperand(0, Op->getOperand(0));
I.setOperand(1, Folded);
return true;
@@ -162,8 +163,7 @@
Constant *C2 = cast(Op1->getOperand(1));
// Fold (op (op V1, C1), (op V2, C2)) ==> (op (op V1, V2), (op C1,C2))
- Constant *Folded = ConstantFoldBinaryInstruction(I.getOpcode(),C1,C2);
- assert(Folded && "Couldn't constant fold commutative operand?");
+ Constant *Folded = ConstantExpr::get(I.getOpcode(), C1, C2);
Instruction *New = BinaryOperator::create(Opcode, Op->getOperand(0),
Op1->getOperand(0),
Op1->getName(), &I);
@@ -185,7 +185,8 @@
// Constants can be considered to be negated values if they can be folded...
if (Constant *C = dyn_cast(V))
- return *Constant::getNullValue(V->getType()) - *C;
+ return ConstantExpr::get(Instruction::Sub,
+ Constant::getNullValue(V->getType()), C);
return 0;
}
@@ -195,7 +196,8 @@
// Constants can be considered to be not'ed values...
if (ConstantIntegral *C = dyn_cast(V))
- return *ConstantIntegral::getAllOnesValue(C->getType()) ^ *C;
+ return ConstantExpr::get(Instruction::Xor,
+ ConstantIntegral::getAllOnesValue(C->getType()),C);
return 0;
}
@@ -256,24 +258,26 @@
// X*C + X --> X * (C+1)
if (dyn_castFoldableMul(LHS) == RHS) {
- Constant *CP1 = *cast(cast(LHS)->getOperand(1)) +
- *ConstantInt::get(I.getType(), 1);
- assert(CP1 && "Couldn't constant fold C + 1?");
+ Constant *CP1 =
+ ConstantExpr::get(Instruction::Add,
+ cast(cast(LHS)->getOperand(1)),
+ ConstantInt::get(I.getType(), 1));
return BinaryOperator::create(Instruction::Mul, RHS, CP1);
}
// X + X*C --> X * (C+1)
if (dyn_castFoldableMul(RHS) == LHS) {
- Constant *CP1 = *cast(cast(RHS)->getOperand(1)) +
- *ConstantInt::get(I.getType(), 1);
- assert(CP1 && "Couldn't constant fold C + 1?");
+ Constant *CP1 =
+ ConstantExpr::get(Instruction::Add,
+ cast(cast(RHS)->getOperand(1)),
+ ConstantInt::get(I.getType(), 1));
return BinaryOperator::create(Instruction::Mul, LHS, CP1);
}
// (A & C1)+(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0
if (Constant *C1 = dyn_castMaskingAnd(LHS))
if (Constant *C2 = dyn_castMaskingAnd(RHS))
- if ((*C1 & *C2)->isNullValue())
+ if (ConstantExpr::get(Instruction::And, C1, C2)->isNullValue())
return BinaryOperator::create(Instruction::Or, LHS, RHS);
return Changed ? &I : 0;
@@ -321,8 +325,10 @@
// X - X*C --> X * (1-C)
if (dyn_castFoldableMul(Op1I) == Op0) {
- Constant *CP1 = *ConstantInt::get(I.getType(), 1) -
- *cast(cast(Op1)->getOperand(1));
+ Constant *CP1 =
+ ConstantExpr::get(Instruction::Sub,
+ ConstantInt::get(I.getType(), 1),
+ cast(cast(Op1)->getOperand(1)));
assert(CP1 && "Couldn't constant fold 1-C?");
return BinaryOperator::create(Instruction::Mul, Op0, CP1);
}
@@ -330,8 +336,10 @@
// X*C - X --> X * (C-1)
if (dyn_castFoldableMul(Op0) == Op1) {
- Constant *CP1 = *cast(cast(Op0)->getOperand(1)) -
- *ConstantInt::get(I.getType(), 1);
+ Constant *CP1 =
+ ConstantExpr::get(Instruction::Sub,
+ cast(cast(Op0)->getOperand(1)),
+ ConstantInt::get(I.getType(), 1));
assert(CP1 && "Couldn't constant fold C - 1?");
return BinaryOperator::create(Instruction::Mul, Op1, CP1);
}
@@ -595,7 +603,7 @@
// (A & C1)^(B & C2) -> (A & C1)|(B & C2) iff C1^C2 == 0
if (Constant *C1 = dyn_castMaskingAnd(Op0))
if (Constant *C2 = dyn_castMaskingAnd(Op1))
- if ((*C1 & *C2)->isNullValue())
+ if (ConstantExpr::get(Instruction::And, C1, C2)->isNullValue())
return BinaryOperator::create(Instruction::Or, Op0, Op1);
return Changed ? &I : 0;
@@ -603,12 +611,14 @@
// AddOne, SubOne - Add or subtract a constant one from an integer constant...
static Constant *AddOne(ConstantInt *C) {
- Constant *Result = *C + *ConstantInt::get(C->getType(), 1);
+ Constant *Result = ConstantExpr::get(Instruction::Add, C,
+ ConstantInt::get(C->getType(), 1));
assert(Result && "Constant folding integer addition failed!");
return Result;
}
static Constant *SubOne(ConstantInt *C) {
- Constant *Result = *C - *ConstantInt::get(C->getType(), 1);
+ Constant *Result = ConstantExpr::get(Instruction::Sub, C,
+ ConstantInt::get(C->getType(), 1));
assert(Result && "Constant folding integer addition failed!");
return Result;
}
@@ -745,10 +755,9 @@
// Calculate bitmask for what gets shifted off the edge...
Constant *C = ConstantIntegral::getAllOnesValue(I.getType());
if (I.getOpcode() == Instruction::Shr)
- C = *C >> *ShiftAmt1C;
+ C = ConstantExpr::getShift(Instruction::Shr, C, ShiftAmt1C);
else
- C = *C << *ShiftAmt1C;
- assert(C && "Couldn't constant fold shift expression?");
+ C = ConstantExpr::getShift(Instruction::Shl, C, ShiftAmt1C);
Instruction *Mask =
BinaryOperator::create(Instruction::And, Op0SI->getOperand(0),
@@ -957,8 +966,9 @@
isa(GEP.getOperand(1))) {
// Replace: gep (gep %P, long C1), long C2, ...
// With: gep %P, long (C1+C2), ...
- Value *Sum = *cast(Src->getOperand(1)) +
- *cast(GEP.getOperand(1));
+ Value *Sum = ConstantExpr::get(Instruction::Add,
+ cast(Src->getOperand(1)),
+ cast(GEP.getOperand(1)));
assert(Sum && "Constant folding of longs failed!?");
GEP.setOperand(0, Src->getOperand(0));
GEP.setOperand(1, Sum);
From lattner at cs.uiuc.edu Tue May 27 11:46:02 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Tue May 27 11:46:02 2003
Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/2003-05-27-ConstExprCrash.ll
Message-ID: <200305271645.LAA31422@apoc.cs.uiuc.edu>
Changes in directory llvm/test/Regression/Transforms/InstCombine:
2003-05-27-ConstExprCrash.ll added (r1.1)
---
Log message:
New testcase
---
Diffs of the changes:
Index: llvm/test/Regression/Transforms/InstCombine/2003-05-27-ConstExprCrash.ll
diff -c /dev/null llvm/test/Regression/Transforms/InstCombine/2003-05-27-ConstExprCrash.ll:1.1
*** /dev/null Tue May 27 11:45:19 2003
--- llvm/test/Regression/Transforms/InstCombine/2003-05-27-ConstExprCrash.ll Tue May 27 11:45:09 2003
***************
*** 0 ****
--- 1,8 ----
+ ; RUN: as < %s | opt -instcombine -disable-output
+
+ %X = global int 5
+ long %test() {
+ %C = add long 1, 2
+ %V = add long cast(int* %X to long), %C
+ ret long %V
+ }
From lattner at cs.uiuc.edu Tue May 27 14:16:01 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Tue May 27 14:16:01 2003
Subject: [llvm-commits] CVS: llvm/tools/gccld/gccld.cpp
Message-ID: <200305271915.OAA32506@apoc.cs.uiuc.edu>
Changes in directory llvm/tools/gccld:
gccld.cpp updated: 1.31 -> 1.32
---
Log message:
Add compatibility option
---
Diffs of the changes:
Index: llvm/tools/gccld/gccld.cpp
diff -u llvm/tools/gccld/gccld.cpp:1.31 llvm/tools/gccld/gccld.cpp:1.32
--- llvm/tools/gccld/gccld.cpp:1.31 Fri May 23 15:27:07 2003
+++ llvm/tools/gccld/gccld.cpp Tue May 27 14:15:11 2003
@@ -68,6 +68,8 @@
CO4("version-script", cl::Hidden, cl::desc("Compatibility option: ignored"));
cl::opt
CO5("eh-frame-hdr", cl::Hidden, cl::desc("Compatibility option: ignored"));
+ cl::opt
+ CO6("r", cl::Hidden, cl::desc("Compatibility option: ignored"));
}
// FileExists - Return true if the specified string is an openable file...
From lattner at cs.uiuc.edu Tue May 27 14:17:01 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Tue May 27 14:17:01 2003
Subject: [llvm-commits] CVS: llvm/lib/VMCore/ConstantHandling.cpp
Message-ID: <200305271916.OAA32536@apoc.cs.uiuc.edu>
Changes in directory llvm/lib/VMCore:
ConstantHandling.cpp updated: 1.30 -> 1.31
---
Log message:
Fix constant folding to ALWAYS work.
---
Diffs of the changes:
Index: llvm/lib/VMCore/ConstantHandling.cpp
diff -u llvm/lib/VMCore/ConstantHandling.cpp:1.30 llvm/lib/VMCore/ConstantHandling.cpp:1.31
--- llvm/lib/VMCore/ConstantHandling.cpp:1.30 Wed May 14 12:51:05 2003
+++ llvm/lib/VMCore/ConstantHandling.cpp Tue May 27 14:16:07 2003
@@ -6,6 +6,7 @@
#include "llvm/ConstantHandling.h"
#include "llvm/iPHINode.h"
+#include "llvm/InstrTypes.h"
#include "llvm/DerivedTypes.h"
#include
@@ -45,26 +46,15 @@
}
}
+ if (isa(I))
+ return ConstantExpr::get(I->getOpcode(), Op0, Op1);
+
switch (I->getOpcode()) {
case Instruction::Cast:
- return ConstRules::get(*Op0, *Op0)->castTo(Op0, I->getType());
- case Instruction::Add: return *Op0 + *Op1;
- case Instruction::Sub: return *Op0 - *Op1;
- case Instruction::Mul: return *Op0 * *Op1;
- case Instruction::Div: return *Op0 / *Op1;
- case Instruction::Rem: return *Op0 % *Op1;
- case Instruction::And: return *Op0 & *Op1;
- case Instruction::Or: return *Op0 | *Op1;
- case Instruction::Xor: return *Op0 ^ *Op1;
-
- case Instruction::SetEQ: return *Op0 == *Op1;
- case Instruction::SetNE: return *Op0 != *Op1;
- case Instruction::SetLE: return *Op0 <= *Op1;
- case Instruction::SetGE: return *Op0 >= *Op1;
- case Instruction::SetLT: return *Op0 < *Op1;
- case Instruction::SetGT: return *Op0 > *Op1;
- case Instruction::Shl: return *Op0 << *Op1;
- case Instruction::Shr: return *Op0 >> *Op1;
+ return ConstantExpr::getCast(Op0, I->getType());
+ case Instruction::Shl:
+ case Instruction::Shr:
+ return ConstantExpr::getShift(I->getOpcode(), Op0, Op1);
case Instruction::GetElementPtr: {
std::vector IdxList;
IdxList.reserve(I->getNumOperands()-1);
@@ -74,7 +64,7 @@
IdxList.push_back(C);
else
return 0; // Non-constant operand
- return ConstantFoldGetElementPtr(Op0, IdxList);
+ return ConstantExpr::getGetElementPtr(Op0, IdxList);
}
default:
return 0;
From brukman at cs.uiuc.edu Tue May 27 15:04:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 15:04:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcV9.td
Message-ID: <200305272003.PAA22586@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
SparcV9.td updated: 1.1 -> 1.2
---
Log message:
Added definitions for a bunch of floating-point instructions.
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/SparcV9.td
diff -u llvm/lib/Target/Sparc/SparcV9.td:1.1 llvm/lib/Target/Sparc/SparcV9.td:1.2
--- llvm/lib/Target/Sparc/SparcV9.td:1.1 Wed May 7 16:52:39 2003
+++ llvm/lib/Target/Sparc/SparcV9.td Tue May 27 15:03:29 2003
@@ -1,5 +1,5 @@
//===- Sparc.td - Target Description for Sparc V9 Target --------*- C++ -*-===//
-//
+// vim:ft=cpp
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
@@ -35,7 +35,15 @@
// Ri - One of the 32 64 bit integer registers
class Ri num> : V9Reg { set Size = 64; field bits<5> Num = num; }
-def G0 : Ri<0>; def G1 : Ri<1>; def G2 : Ri<2>; def G3 : Ri<3>;
+def G0 : Ri< 0>; def G1 : Ri< 1>; def G2 : Ri< 2>; def G3 : Ri< 3>;
+def G4 : Ri< 4>; def G5 : Ri< 5>; def G6 : Ri< 6>; def G7 : Ri< 7>;
+def O0 : Ri< 8>; def O1 : Ri< 9>; def O2 : Ri<10>; def O3 : Ri<11>;
+def O4 : Ri<12>; def O5 : Ri<13>; def O6 : Ri<14>; def O7 : Ri<15>;
+def L0 : Ri<16>; def L1 : Ri<17>; def L2 : Ri<18>; def L3 : Ri<19>;
+def L4 : Ri<20>; def L5 : Ri<21>; def L6 : Ri<22>; def L7 : Ri<23>;
+def I0 : Ri<24>; def I1 : Ri<25>; def I2 : Ri<26>; def I3 : Ri<27>;
+def I4 : Ri<28>; def I5 : Ri<29>; def I6 : Ri<30>; def I7 : Ri<31>;
+// Floating-point registers?
// ...
@@ -67,6 +75,16 @@
set Inst{24-22} = op2;
}
+// Format 2.1 instructions
+class F2_1 : F2 {
+ bits<5> rd;
+ bits<22> imm;
+
+ set Name = name;
+ set Inst{29-25} = rd;
+ set Inst{21-0} = imm;
+}
+
class F2_br : F2 { // Format 2 Branch instruction
bit annul; // All branches have an annul bit
set Inst{29} = annul;
@@ -129,13 +147,17 @@
}
// F3_rs1rd - Common superclass of instructions that use rs1 & rd...
-class F3_rs1rd : F3_rs1 {
+class F3_rs1rd : F3 {
+ // Added rs1 here manually to have rd appear before rs1
+ // Formerly inherited directly from F3_rs1
bits<5> rd;
+ bits<5> rs1;
set Inst{29-25} = rd;
+ set Inst{18-14} = rs1;
}
// F3_rs1rdrs2 - Common superclass of instructions with rs1, rd, & rs2 fields
-class F3_rs1rdrs2 : F3_rs1 {
+class F3_rs1rdrs2 : F3_rs1rd {
bits<5> rs2;
set Inst{4-0} = rs2;
}
@@ -172,18 +194,55 @@
set Inst{4-0} = rs2;
}
-class F3_4 opVal, bits<6> op3val, string name> : F3_rs1 {
+class F3_4 opVal, bits<6> op3Val, string name> : F3_rs1 {
bits<13> simm;
set op = opVal;
- set op3 = op3val;
+ set op3 = op3Val;
set Name = name;
//set Inst{29-25} = dontcare;
set Inst{13} = 1;
set Inst{12-0} = simm;
}
+class F3_11 opVal, bits<6> op3Val, string name> : F3_rs1rdrs2 {
+ bit x;
+ set op = opVal;
+ set op3 = op3Val;
+ set Name = name;
+ set Inst{13} = 0; // i field = 0
+ set Inst{12} = x;
+ //set Inst{11-5} = dontcare;
+}
+
+class F3_12 opVal, bits<6> op3Val, string name> : F3 {
+ bits<5> shcnt;
+
+ set Name = name;
+ set Inst{13} = 1; // i field = 1
+ set Inst{12} = 0; // x field = 0
+ //set Inst{11-5} = dontcare;
+ set Inst{4-0} = shcnt;
+}
+class F3_13 opVal, bits<6> op3Val, string name> : F3 {
+ bits<6> shcnt;
+ set Name = name;
+ set Inst{13} = 1; // i field = 1
+ set Inst{12} = 1; // x field = 1
+ //set Inst{11-6} = dontcare;
+ set Inst{5-0} = shcnt;
+}
+
+class F3_14 opVal, bits<6> op3val,
+ bits<9> opfval, string name> : F3_rs1rdrs2 {
+ set op = opVal;
+ set op3 = op3val;
+ set Name = name;
+ //set Inst{18-14} = dontcare;
+ set Inst{13-5} = opfval;
+}
+
class F3_16 opVal, bits<6> op3val,
bits<9> opfval, string name> : F3_rs1rdrs2 {
set op = opVal;
@@ -207,12 +266,12 @@
// Section A.2: p161
def ADDr : F3_1<2, 0b000000, "add">; // add r, r, r
def ADDi : F3_2<2, 0b000000, "add">; // add r, r, i
-def ADDCCr : F3_1<2, 0b010000, "addcc">; // addcc r, r, r
-def ADDCCi : F3_2<2, 0b010000, "addcc">; // addcc r, r, i
+def ADDccr : F3_1<2, 0b010000, "addcc">; // addcc r, r, r
+def ADDcci : F3_2<2, 0b010000, "addcc">; // addcc r, r, i
def ADDCr : F3_1<2, 0b001000, "addC">; // addC r, r, r
def ADDCi : F3_2<2, 0b001000, "addC">; // addC r, r, i
-def ADDCCCr : F3_1<2, 0b011000, "addCcc">; // addCcc r, r, r
-def ADDCCCi : F3_2<2, 0b011000, "addCcc">; // addCcc r, r, i
+def ADDCccr : F3_1<2, 0b011000, "addCcc">; // addCcc r, r, r
+def ADDCcci : F3_2<2, 0b011000, "addCcc">; // addCcc r, r, i
// Section A.3: p162
set op2 = 0b011 in {
@@ -247,24 +306,24 @@
}
// Section A.5: p167
-set op2 = 0b101 in {
- def FBPA : F2_3<0b1000, "fbpa">; // Branch always
- def FBPN : F2_3<0b0000, "fbpn">; // Branch never
- def FBPU : F2_3<0b0111, "fbpu">; // Branch on unordered
- def FBPG : F2_3<0b0110, "fbpg">; // Branch >
- def FBPUG : F2_3<0b0101, "fbpug">; // Branch on unordered or >
- def FBPL : F2_3<0b0100, "fbpl">; // Branch <
- def FBPUL : F2_3<0b0011, "fbpul">; // Branch on unordered or <
- def FBPLG : F2_3<0b0010, "fbplg">; // Branch < or >
- def FBPNE : F2_3<0b0001, "fbpne">; // Branch !=
- def FBPE : F2_3<0b1001, "fbpe">; // Branch ==
- def FBPUE : F2_3<0b1010, "fbpue">; // Branch on unordered or ==
- def FBPGE : F2_3<0b1011, "fbpge">; // Branch > or ==
- def FBPUGE : F2_3<0b1100, "fbpuge">; // Branch unord or > or ==
- def FBPLE : F2_3<0b1101, "fbple">; // Branch < or ==
- def FBPULE : F2_3<0b1110, "fbpule">; // Branch unord or < or ==
- def FBPO : F2_3<0b1111, "fbpo">; // Branch on ordered
-}
+//set op2 = 0b101 in {
+ //def FBPA : F2_3<0b1000, "fbpa">; // Branch always
+ //def FBPN : F2_3<0b0000, "fbpn">; // Branch never
+ //def FBPU : F2_3<0b0111, "fbpu">; // Branch on unordered
+ //def FBPG : F2_3<0b0110, "fbpg">; // Branch >
+ //def FBPUG : F2_3<0b0101, "fbpug">; // Branch on unordered or >
+ //def FBPL : F2_3<0b0100, "fbpl">; // Branch <
+ //def FBPUL : F2_3<0b0011, "fbpul">; // Branch on unordered or <
+ //def FBPLG : F2_3<0b0010, "fbplg">; // Branch < or >
+ //def FBPNE : F2_3<0b0001, "fbpne">; // Branch !=
+ //def FBPE : F2_3<0b1001, "fbpe">; // Branch ==
+ //def FBPUE : F2_3<0b1010, "fbpue">; // Branch on unordered or ==
+ //def FBPGE : F2_3<0b1011, "fbpge">; // Branch > or ==
+ //def FBPUGE : F2_3<0b1100, "fbpuge">; // Branch unord or > or ==
+ //def FBPLE : F2_3<0b1101, "fbple">; // Branch < or ==
+ //def FBPULE : F2_3<0b1110, "fbpule">; // Branch unord or < or ==
+ //def FBPO : F2_3<0b1111, "fbpo">; // Branch on ordered
+//}
// Section A.6: p170: Bicc
set isDeprecated = 1 in {
@@ -289,25 +348,24 @@
}
// Section A.7: p172
-set op2 = 0b001 in {
- def BPA : F2_3<0b1000, "bpa">; // Branch always
- def BPN : F2_3<0b0000, "bpn">; // Branch never
- def BPNE : F2_3<0b1001, "bpne">; // Branch !=
- def BPE : F2_3<0b0001, "bpe">; // Branch ==
- def BPG : F2_3<0b1010, "bpg">; // Branch >
- def BPLE : F2_3<0b0010, "bple">; // Branch <=
- def BPGE : F2_3<0b1011, "bpge">; // Branch >=
- def BPL : F2_3<0b0011, "bpl">; // Branch <
- def BPGU : F2_3<0b1100, "bpgu">; // Branch unsigned >
-
- def BPLEU : F2_3<0b0100, "bpleu">; // Branch unsigned <=
- def BPCC : F2_3<0b1101, "bpcc">; // Branch unsigned >=
- def BPCS : F2_3<0b0101, "bpcs">; // Branch unsigned <=
- def BPPOS : F2_3<0b1110, "bppos">; // Branch on positive
- def BPNEG : F2_3<0b0110, "bpneg">; // Branch on negative
- def BPVC : F2_3<0b1111, "bpvc">; // Branch on overflow clear
- def BPVS : F2_3<0b0111, "bpvs">; // Branch on overflow set
-}
+//set op2 = 0b001 in {
+// def BPA : F2_3<0b1000, "bpa">; // Branch always
+// def BPN : F2_3<0b0000, "bpn">; // Branch never
+// def BPNE : F2_3<0b1001, "bpne">; // Branch !=
+// def BPE : F2_3<0b0001, "bpe">; // Branch ==
+// def BPG : F2_3<0b1010, "bpg">; // Branch >
+// def BPLE : F2_3<0b0010, "bple">; // Branch <=
+// def BPGE : F2_3<0b1011, "bpge">; // Branch >=
+// def BPL : F2_3<0b0011, "bpl">; // Branch <
+// def BPGU : F2_3<0b1100, "bpgu">; // Branch unsigned >
+// def BPLEU : F2_3<0b0100, "bpleu">; // Branch unsigned <=
+// def BPCC : F2_3<0b1101, "bpcc">; // Branch unsigned >=
+// def BPCS : F2_3<0b0101, "bpcs">; // Branch unsigned <=
+// def BPPOS : F2_3<0b1110, "bppos">; // Branch on positive
+// def BPNEG : F2_3<0b0110, "bpneg">; // Branch on negative
+// def BPVC : F2_3<0b1111, "bpvc">; // Branch on overflow clear
+// def BPVS : F2_3<0b0111, "bpvs">; // Branch on overflow set
+//}
// Section A.8: p175 - CALL - the only Format #1 instruction
def CALL : InstV9 {
@@ -323,22 +381,23 @@
// Section A.10: Divide (64-bit / 32-bit) - p178
-set isDeprecated = 1 in {
- def UDIVr : F3_1<2, 0b001110, "udiv">; // udiv r, r, r
- def UDIVi : F3_2<2, 0b001110, "udiv">; // udiv r, r, i
- def SDIVr : F3_1<2, 0b001111, "sdiv">; // sdiv r, r, r
- def SDIVi : F3_2<2, 0b001111, "sdiv">; // sdiv r, r, i
- def UDIVCCr : F3_1<2, 0b011110, "udivcc">; // udivcc r, r, r
- def UDIVCCi : F3_2<2, 0b011110, "udivcc">; // udivcc r, r, i
- def SDIVCCr : F3_1<2, 0b011111, "sdivcc">; // sdivcc r, r, r
- def SDIVCCi : F3_2<2, 0b011111, "sdivcc">; // sdivcc r, r, i
-}
+// Not used in the Sparc backend
+//set isDeprecated = 1 in {
+ //def UDIVr : F3_1<2, 0b001110, "udiv">; // udiv r, r, r
+ //def UDIVi : F3_2<2, 0b001110, "udiv">; // udiv r, r, i
+ //def SDIVr : F3_1<2, 0b001111, "sdiv">; // sdiv r, r, r
+ //def SDIVi : F3_2<2, 0b001111, "sdiv">; // sdiv r, r, i
+ //def UDIVCCr : F3_1<2, 0b011110, "udivcc">; // udivcc r, r, r
+ //def UDIVCCi : F3_2<2, 0b011110, "udivcc">; // udivcc r, r, i
+ //def SDIVCCr : F3_1<2, 0b011111, "sdivcc">; // sdivcc r, r, r
+ //def SDIVCCi : F3_2<2, 0b011111, "sdivcc">; // sdivcc r, r, i
+//}
// Section A.11: DONE and RETRY - p181
-set isPrivileged = 1 in {
- def DONE : F3_18<0, "done">; // done
- def RETRY : F3_18<1, "retry">; // retry
-}
+//set isPrivileged = 1 in {
+ //def DONE : F3_18<0, "done">; // done
+ //def RETRY : F3_18<1, "retry">; // retry
+//}
// Section A.12: Floating-Point Add and Subtract - p182
def FADDS : F3_16<2, 0b110100, 0x41, "fadds">; // fadds f, f, f
@@ -348,12 +407,269 @@
def FSUBD : F3_16<2, 0b110100, 0x46, "fsubd">; // fsubd f, f, f
def FSUBQ : F3_16<2, 0b110100, 0x47, "fsubq">; // fsubq f, f, f
-//
-// ...
-//
+// Section A.17: Floating-Point Move - p164
+def FMOVS : F3_14<2, 0b110100, 0b000000001, "fmovs">; // fmovs r, r
+def FMOVD : F3_14<2, 0b110100, 0b000000010, "fmovs">; // fmovd r, r
+//def FMOVQ : F3_14<2, 0b110100, 0b000000011, "fmovs">; // fmovq r, r
+def FNEGS : F3_14<2, 0b110100, 0b000000101, "fnegs">; // fnegs r, r
+def FNEGD : F3_14<2, 0b110100, 0b000000110, "fnegs">; // fnegs r, r
+//def FNEGQ : F3_14<2, 0b110100, 0b000000111, "fnegs">; // fnegs r, r
+def FABSS : F3_14<2, 0b110100, 0b000001001, "fabss">; // fabss r, r
+def FABSD : F3_14<2, 0b110100, 0b000001010, "fabss">; // fabss r, r
+//def FABSQ : F3_14<2, 0b110100, 0b000001011, "fabss">; // fabss r, r
+
+// Section A.18: Floating-Point Multiply and Divide - p165
+def FMULS : F3_16<2, 0b110100, 0b001001001, "fmuls">; // fmuls r, r, r
+def FMULD : F3_16<2, 0b110100, 0b001001010, "fmuld">; // fmuld r, r, r
+def FMULQ : F3_16<2, 0b110100, 0b001001011, "fmulq">; // fmulq r, r, r
+def FSMULD : F3_16<2, 0b110100, 0b001101001, "fsmuld">; // fsmuls r, r, r
+def FDMULQ : F3_16<2, 0b110100, 0b001101110, "fdmulq">; // fdmuls r, r, r
+def FDIVS : F3_16<2, 0b110100, 0b001001101, "fdivs">; // fdivs r, r, r
+def FDIVD : F3_16<2, 0b110100, 0b001001110, "fdivs">; // fdivd r, r, r
+def FDIVQ : F3_16<2, 0b110100, 0b001001111, "fdivs">; // fdivq r, r, r
+
+// Section A.19: Floating-Point Square Root - p166
+def FSQRTS : F3_14<2, 0b110100, 0b000101001, "fsqrts">; // fsqrts r, r
+def FSQRTD : F3_14<2, 0b110100, 0b000101010, "fsqrts">; // fsqrts r, r
+def FSQRTQ : F3_14<2, 0b110100, 0b000101011, "fsqrts">; // fsqrts r, r
+
+// Section A.24: Jump and Link
+// Mimicking the Sparc's instr def...
+def JMPLCALLr : F3_1<2, 0b111000, "jmpl">; // jmpl [r+r], r
+def JMPLCALLi : F3_1<2, 0b111000, "jmpl">; // jmpl [r+i], r
+def JMPLRETr : F3_1<2, 0b111000, "jmpl">; // jmpl [r+r], r
+def JMPLRETi : F3_1<2, 0b111000, "jmpl">; // jmpl [r+i], r
+
+// FIXME: FCMPS, FCMPD, FCMPQ !!!
+// FIXME: FMULS, FMULD, FMULQ, ...
+
+// Section A.25: Load Floating-Point - p173
+def LDFr : F3_1<3, 0b100000, "ld">; // ld [r+r], r
+def LDFi : F3_2<3, 0b100000, "ld">; // ld [r+i], r
+def LDDFr : F3_1<3, 0b100011, "ldd">; // ldd [r+r], r
+def LDDFi : F3_2<3, 0b100011, "ldd">; // ldd [r+i], r
+def LDQFr : F3_1<3, 0b100010, "ldq">; // ldq [r+r], r
+def LDQFi : F3_2<3, 0b100010, "ldq">; // ldq [r+i], r
+set isDeprecated = 1 in {
+ set rd = 0 in {
+ def LDFSRr : F3_1<3, 0b100001, "ld">; // ld [r+r], r
+ def LDFSRi : F3_2<3, 0b100001, "ld">; // ld [r+i], r
+ }
+}
+set rd = 1 in {
+ def LDXFSRr : F3_1<3, 0b100001, "ldx">; // ldx [r+r], r
+ def LDXFSRi : F3_2<3, 0b100001, "ldx">; // ldx [r+i], r
+}
+
+// Section A.27: Load Integer - p178
+def LDSBr : F3_1<3, 0b001001, "ldsb">; // ldsb [r+r], r
+def LDSBi : F3_2<3, 0b001001, "ldsb">; // ldsb [r+i], r
+def LDSHr : F3_1<3, 0b001010, "ldsh">; // ldsh [r+r], r
+def LDSHi : F3_2<3, 0b001010, "ldsh">; // ldsh [r+i], r
+def LDSWr : F3_1<3, 0b001000, "ldsw">; // ldsh [r+r], r
+def LDSWi : F3_2<3, 0b001000, "ldsw">; // ldsh [r+i], r
+def LDUBr : F3_1<3, 0b000001, "ldub">; // ldub [r+r], r
+def LDUBi : F3_2<3, 0b000001, "ldub">; // ldub [r+i], r
+def LDUHr : F3_1<3, 0b000010, "lduh">; // lduh [r+r], r
+def LDUHi : F3_2<3, 0b000010, "lduh">; // lduh [r+i], r
+// synonym: LD
+def LDUWr : F3_1<3, 0b000000, "lduw">; // lduw [r+r], r
+def LDUWi : F3_2<3, 0b000000, "lduw">; // lduw [r+i], r
+// LDD should no longer be used, LDX should be used instead
+def LDXr : F3_1<3, 0b001011, "ldx">; // ldx [r+r], r
+def LDXi : F3_2<3, 0b001011, "ldx">; // ldx [r+i], r
+//set isDeprecated = 1 in {
+// def LDDr : F3_1<3, 0b000011, "ldd">; // ldd [r+r], r
+// def LDDi : F3_2<3, 0b000011, "ldd">; // ldd [r+i], r
+//}
+
+// Section A.31: Logical operations
+def ANDr : F3_1<2, 0b000001, "and">; // and r, r, r
+def ANDi : F3_2<2, 0b000001, "and">; // and r, r, i
+def ANDccr : F3_1<2, 0b010001, "andcc">; // andcc r, r, r
+def ANDcci : F3_2<2, 0b010001, "andcc">; // andcc r, r, i
+def ANDNr : F3_1<2, 0b000101, "andn">; // andn r, r, r
+def ANDNi : F3_2<2, 0b000101, "andn">; // andn r, r, i
+def ANDNccr : F3_1<2, 0b010101, "andncc">; // andncc r, r, r
+def ANDNcci : F3_2<2, 0b010101, "andncc">; // andncc r, r, i
+
+def ORr : F3_1<2, 0b000010, "or">; // or r, r, r
+def ORi : F3_2<2, 0b000010, "or">; // or r, r, i
+def ORccr : F3_1<2, 0b010010, "orcc">; // orcc r, r, r
+def ORcci : F3_2<2, 0b010010, "orcc">; // orcc r, r, i
+def ORNr : F3_1<2, 0b000110, "orn">; // orn r, r, r
+def ORNi : F3_2<2, 0b000110, "orn">; // orn r, r, i
+def ORNccr : F3_1<2, 0b010110, "orncc">; // orncc r, r, r
+def ORNcci : F3_2<2, 0b010110, "orncc">; // orncc r, r, i
+
+def XORr : F3_1<2, 0b000011, "xor">; // xor r, r, r
+def XORi : F3_2<2, 0b000011, "xor">; // xor r, r, i
+def XORccr : F3_1<2, 0b010011, "xorcc">; // xorcc r, r, r
+def XORcci : F3_2<2, 0b010011, "xorcc">; // xorcc r, r, i
+def XNORr : F3_1<2, 0b000111, "xnor">; // xnor r, r, r
+def XNORi : F3_2<2, 0b000111, "xnor">; // xnor r, r, i
+def XNORccr : F3_1<2, 0b010111, "xnorcc">; // xnorcc r, r, r
+def XNORcci : F3_2<2, 0b010111, "xnorcc">; // xnorcc r, r, i
+
+#if 0
+// Section A.33: Move Floating-Point Register on Condition (FMOVcc)
+// For integer condition codes
+def FMOVA : F4_7<2, 0b110101, 0b1000, "fmova">; // fmova r, r
+def FMOVN : F4_7<2, 0b110101, 0b0000, "fmovn">; // fmovn r, r
+def FMOVNE : F4_7<2, 0b110101, 0b1001, "fmovne">; // fmovne r, r
+def FMOVE : F4_7<2, 0b110101, 0b0000, "fmove">; // fmove r, r
+def FMOVG : F4_7<2, 0b110101, 0b1010, "fmovg">; // fmovg r, r
+def FMOVLE : F4_7<2, 0b110101, 0b0000, "fmovle">; // fmovle r, r
+def FMOVGE : F4_7<2, 0b110101, 0b1011, "fmovge">; // fmovge r, r
+def FMOVL : F4_7<2, 0b110101, 0b0011, "fmovl">; // fmovl r, r
+def FMOVGU : F4_7<2, 0b110101, 0b1100, "fmovgu">; // fmovgu r, r
+def FMOVLEU : F4_7<2, 0b110101, 0b0100, "fmovleu">; // fmovleu r, r
+def FMOVCC : F4_7<2, 0b110101, 0b1101, "fmovcc">; // fmovcc r, r
+def FMOVCS : F4_7<2, 0b110101, 0b0101, "fmovcs">; // fmovcs r, r
+def FMOVPOS : F4_7<2, 0b110101, 0b1110, "fmovpos">; // fmovpos r, r
+def FMOVNEG : F4_7<2, 0b110101, 0b0110, "fmovneg">; // fmovneg r, r
+def FMOVVC : F4_7<2, 0b110101, 0b1111, "fmovvc">; // fmovvc r, r
+def FMOVVS : F4_7<2, 0b110101, 0b0111, "fmovvs">; // fmovvs r, r
+
+// For floating-point condition codes
+def FMOVFA : F4_7<2, 0b110101, 0b0100, "fmovfa">; // fmovfa r, r
+def FMOVFN : F4_7<2, 0b110101, 0b0000, "fmovfn">; // fmovfa r, r
+def FMOVFU : F4_7<2, 0b110101, 0b0111, "fmovfu">; // fmovfu r, r
+def FMOVFG : F4_7<2, 0b110101, 0b0110, "fmovfg">; // fmovfg r, r
+def FMOVFUG : F4_7<2, 0b110101, 0b0101, "fmovfug">; // fmovfug r, r
+def FMOVFL : F4_7<2, 0b110101, 0b0100, "fmovfl">; // fmovfl r, r
+def FMOVFUL : F4_7<2, 0b110101, 0b0011, "fmovful">; // fmovful r, r
+def FMOVFLG : F4_7<2, 0b110101, 0b0010, "fmovflg">; // fmovflg r, r
+def FMOVFNE : F4_7<2, 0b110101, 0b0001, "fmovfne">; // fmovfne r, r
+def FMOVFE : F4_7<2, 0b110101, 0b1001, "fmovfe">; // fmovfe r, r
+def FMOVFUE : F4_7<2, 0b110101, 0b1010, "fmovfue">; // fmovfue r, r
+def FMOVGE : F4_7<2, 0b110101, 0b1011, "fmovge">; // fmovge r, r
+def FMOVFUGE : F4_7<2, 0b110101, 0b1100, "fmovfuge">; // fmovfuge r, r
+def FMOVFLE : F4_7<2, 0b110101, 0b1101, "fmovfle">; // fmovfle r, r
+def FMOVFULE : F4_7<2, 0b110101, 0b1110, "fmovfule">; // fmovfule r, r
+def FMOVFO : F4_7<2, 0b110101, 0b1111, "fmovfo">; // fmovfo r, r
+#endif
+
+// Section A.37: Multiply and Divide (64-bit) - p199
+def MULXr : F3_1<2, 0b001001, "mulx">; // mulx r, r, r
+def SDIVXr : F3_1<2, 0b101101, "sdivx">; // mulx r, r, r
+def UDIVXr : F3_1<2, 0b001101, "udivx">; // mulx r, r, r
+def MULXi : F3_2<2, 0b001001, "mulx">; // mulx r, i, r
+def SDIVXi : F3_2<2, 0b101101, "sdivx">; // mulx r, i, r
+def UDIVXi : F3_2<2, 0b001101, "udivx">; // mulx r, i, r
+
+// Section A.38: Multiply (32-bit) - p200
+// Not used in the Sparc backend?
+//set Inst{13} = 0 in {
+// def UMULr : F3_1<2, 0b001010, "umul">; // umul r, r, r
+// def SMULr : F3_1<2, 0b001011, "smul">; // smul r, r, r
+// def UMULCCr : F3_1<2, 0b011010, "umulcc">; // mulcc r, r, r
+// def SMULCCr : F3_1<2, 0b011011, "smulcc">; // smulcc r, r, r
+//}
+//set Inst{13} = 1 in {
+// def UMULi : F3_1<2, 0b001010, "umul">; // umul r, i, r
+// def SMULi : F3_1<2, 0b001011, "smul">; // smul r, i, r
+// def UMULCCi : F3_1<2, 0b011010, "umulcc">; // umulcc r, i, r
+// def SMULCCi : F3_1<2, 0b011011, "smulcc">; // smulcc r, i, r
+//}
+
+// Section A.40: No operation - p204
+// NOP is really a pseudo-instruction (special case of SETHI)
+set op2 = 0b100 in {
+ set rd = 0 in {
+ set imm = 0 in {
+ def NOP : F2_1<"nop">; // nop
+ }
+ }
+}
-// Section A.45: RETURN - p240
+// Section A.45: RETURN - p216
set isReturn = 1 in {
def RETURNr : F3_3<2, 0b111001, "return">; // return
def RETURNi : F3_4<2, 0b111001, "return">; // return
}
+
+// Section A.46: SAVE and RESTORE - p217
+def SAVEr : F3_1<2, 0b111100, "save">; // save r, r, r
+def SAVEi : F3_2<2, 0b111100, "save">; // save r, i, r
+def RESTOREr : F3_1<2, 0b111101, "restore">; // restore r, r, r
+def RESTOREi : F3_2<2, 0b111101, "restore">; // restore r, i, r
+
+// Section A.47: SAVED and RESTORED - p219
+// FIXME: add these instrs
+
+// Section A.48: SETHI - p220
+set op2 = 0b100 in {
+ def SETHI : F2_1<"sethi">; // sethi
+}
+
+// Section A.49: Shift - p221
+// uses 5 least significant bits of rs2
+//set x = 0 in {
+// def SLLr5 : F3_11<2, 0b100101, "sll">; // sll r, r, r
+// def SRLr5 : F3_11<2, 0b100110, "srl">; // srl r, r, r
+// def SRAr5 : F3_11<2, 0b100111, "sra">; // sra r, r, r
+// def SLLXr5 : F3_11<2, 0b100101, "sllx">; // sllx r, r, r
+// def SRLXr5 : F3_11<2, 0b100110, "srlx">; // srlx r, r, r
+// def SRAXr5 : F3_11<2, 0b100111, "srax">; // srax r, r, r
+//}
+// uses 6 least significant bits of rs2
+set x = 1 in {
+ // def SLLr6 : F3_11<2, 0b100101, "sll">; // sll r, r, r
+ // def SRLr6 : F3_11<2, 0b100110, "srl">; // srl r, r, r
+ // def SRAr6 : F3_11<2, 0b100111, "sra">; // sra r, r, r
+ def SLLXr6 : F3_11<2, 0b100101, "sllx">; // sllx r, r, r
+ def SRLXr6 : F3_11<2, 0b100110, "srlx">; // srlx r, r, r
+ def SRAXr6 : F3_11<2, 0b100111, "srax">; // srax r, r, r
+}
+
+//def SLLi5 : F3_12<2, 0b100101, "sll">; // sll r, shcnt32, r
+//def SRLi5 : F3_12<2, 0b100110, "srl">; // srl r, shcnt32, r
+//def SRAi5 : F3_12<2, 0b100111, "sra">; // sra r, shcnt32, r
+//def SLLXi5 : F3_12<2, 0b100101, "sllx">; // sllx r, shcnt32, r
+//def SRLXi5 : F3_12<2, 0b100110, "srlx">; // srlx r, shcnt32, r
+//def SRAXi5 : F3_12<2, 0b100111, "srax">; // srax r, shcnt32, r
+
+//def SLLi6 : F3_13<2, 0b100101, "sll">; // sll r, shcnt64, r
+//def SRLi6 : F3_13<2, 0b100110, "srl">; // srl r, shcnt64, r
+//def SRAi6 : F3_13<2, 0b100111, "sra">; // sra r, shcnt64, r
+def SLLXi6 : F3_13<2, 0b100101, "sllx">; // sllx r, shcnt64, r
+def SRLXi6 : F3_13<2, 0b100110, "srlx">; // srlx r, shcnt64, r
+def SRAXi6 : F3_13<2, 0b100111, "srax">; // srax r, shcnt64, r
+
+// Section A.52: Store Floating-point -p225
+def STFr : F3_1<3, 0b100100, "st">; // st r, [r+r]
+def STFi : F3_2<3, 0b100100, "st">; // st r, [r+i]
+def STDFr : F3_1<3, 0b100111, "std">; // std r, [r+r]
+def STDFi : F3_2<3, 0b100111, "std">; // std r, [r+i]
+// Not currently used in the Sparc backend
+//def STQFr : F3_1<3, 0b100110, "stq">; // stq r, [r+r]
+//def STQFi : F3_2<3, 0b100110, "stq">; // stq r, [r+i]
+set isDeprecated = 1 in {
+ def STFSRr : F3_1<3, 0b100101, "st">; // st r, [r+r]
+ def STFSRi : F3_2<3, 0b100101, "st">; // st r, [r+i]
+}
+def STXFSRr : F3_1<3, 0b100101, "stq">; // stx r, [r+r]
+def STXFSRi : F3_2<3, 0b100101, "stq">; // stx r, [r+i]
+
+// Section A.54: Store Integer - p229
+def STBr : F3_1<3, 0b000101, "stb">; // stb r, [r+r]
+def STBi : F3_2<3, 0b000101, "stb">; // stb r, [r+i]
+def STHr : F3_1<3, 0b000110, "stb">; // stb r, [r+r]
+def STHi : F3_2<3, 0b000110, "stb">; // stb r, [r+i]
+def STWr : F3_1<3, 0b000100, "stb">; // stb r, [r+r]
+def STWi : F3_2<3, 0b000100, "stb">; // stb r, [r+i]
+def STXr : F3_1<3, 0b001110, "stb">; // stb r, [r+r]
+def STXi : F3_2<3, 0b001110, "stb">; // stb r, [r+i]
+
+// Floating point store...
+
+// Section A.56: Subtract - p233
+def SUBr : F3_1<2, 0b000100, "sub">; // sub r, r, r
+def SUBi : F3_1<2, 0b000100, "sub">; // sub r, i, r
+def SUBccr : F3_1<2, 0b010100, "subcc">; // subcc r, r, r
+def SUBcci : F3_1<2, 0b010100, "subcc">; // subcc r, i, r
+def SUBCr : F3_1<2, 0b001100, "subc">; // subc r, r, r
+def SUBCi : F3_1<2, 0b001100, "subc">; // subc r, i, r
+def SUBCccr : F3_1<2, 0b011100, "subccc">; // subccc r, r, r
+def SUBCcci : F3_1<2, 0b011100, "subccc">; // subccc r, i, r
From brukman at cs.uiuc.edu Tue May 27 15:06:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 15:06:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/AddRegNumToValues.cpp
Message-ID: <200305272005.PAA22613@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
AddRegNumToValues.cpp added (r1.1)
---
Log message:
This file provides the `glue' to turn the Value*-based MachineInstrs that
the Sparc instruction selector produces to the unsigned-register-based
MachineInstrs that the target-independent register allocators in the JIT prefer.
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/AddRegNumToValues.cpp
diff -c /dev/null llvm/lib/Target/Sparc/AddRegNumToValues.cpp:1.1
*** /dev/null Tue May 27 15:05:37 2003
--- llvm/lib/Target/Sparc/AddRegNumToValues.cpp Tue May 27 15:05:27 2003
***************
*** 0 ****
--- 1,64 ----
+ //===-- AddRegNumToValues.cpp - Adds unsigned register indices for Value* -===//
+ //
+ // This is a placeholder pass, just so that it doesn't intrude too much into
+ // the MachineOperand class:
+ // * The Sparc back-end uses Value* in instructions for dataflow
+ // * The RegisterAllocator in the JIT expects unsigned register numbers instead
+ // of Value*
+ //
+ // This pass is an attempt to bridge the gap between the two, without putting an
+ // explicit conversion in the shortest path (i.e., the original LLC codegen).
+ //
+ //===----------------------------------------------------------------------===//
+
+ #include "llvm/CodeGen/Passes.h"
+ #include "llvm/CodeGen/MachineFunctionPass.h"
+ #include "llvm/CodeGen/MachineInstr.h"
+ #include "SparcInternals.h"
+
+ namespace {
+ struct AddRegNumToValues : MachineFunctionPass {
+
+ AddRegNumToValues() {}
+ bool runOnMachineFunction(MachineFunction &F);
+ };
+
+ static RegisterOpt
+ X("add-regnum", "Add reg numbers to Values", createAddRegNumToValuesPass);
+ }
+
+ bool AddRegNumToValues::runOnMachineFunction(MachineFunction &F) {
+ unsigned regNum = MRegisterInfo::FirstVirtualRegister;
+ std::map Value2RegMap;
+
+ for (MachineFunction::iterator i = F.begin(), e = F.end(); i != e; ++i) {
+ MachineBasicBlock &BB = *i;
+ for (MachineBasicBlock::iterator Bi = BB.begin(), Be = BB.end();
+ Bi != Be; ++Bi)
+ {
+ MachineInstr *MI = *Bi;
+
+ // Loop over uses, move from memory into registers
+ for (int i = MI->getNumOperands()-1; i >= 0; --i) {
+ MachineOperand &op = MI->getOperand(i);
+
+ Value *val = op.getVRegValueOrNull();
+ if (Instruction *inst = dyn_cast(val)) {
+ if (Value2RegMap[val] != 0) {
+ MI->SetRegForOperand(i, Value2RegMap[val]);
+ } else {
+ MI->SetRegForOperand(i, regNum);
+ Value2RegMap[val] = regNum++;
+ }
+ }
+ }
+ }
+ }
+
+ Value2RegMap.clear();
+ return false;
+ }
+
+ Pass *createAddRegNumToValuesPass() {
+ return new AddRegNumToValues();
+ }
From brukman at cs.uiuc.edu Tue May 27 15:09:02 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 15:09:02 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp .cvsignore Makefile
Message-ID: <200305272008.PAA22644@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
SparcV9CodeEmitter.cpp added (r1.1)
.cvsignore added (r1.1)
Makefile updated: 1.13 -> 1.14
---
Log message:
SparcV9CodeEmitter.cpp is a part of the Sparc code emitter. The main function
that assembles instructions is generated via TableGen (and hence must be built
before building this directory, but that's already the case in the top-level
Makefile).
Also added is .cvsignore to ignore the generated file `SparcV9CodeEmitter.inc',
which is included by SparcV9CodeEmitter.cpp .
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp
diff -c /dev/null llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.1
*** /dev/null Tue May 27 15:08:08 2003
--- llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp Tue May 27 15:07:58 2003
***************
*** 0 ****
--- 1,90 ----
+ #include "llvm/PassManager.h"
+ #include "llvm/CodeGen/MachineCodeEmitter.h"
+ #include "llvm/CodeGen/MachineFunctionPass.h"
+ #include "llvm/CodeGen/MachineInstr.h"
+ #include "SparcInternals.h"
+
+ namespace {
+ class SparcV9CodeEmitter : public MachineFunctionPass {
+ MachineCodeEmitter &MCE;
+
+ public:
+ SparcV9CodeEmitter(MachineCodeEmitter &M) : MCE(M) {}
+
+ bool runOnMachineFunction(MachineFunction &F);
+
+ private:
+ int64_t getMachineOpValue(MachineOperand &MO);
+ unsigned getValueBit(int64_t Val, unsigned bit);
+
+ void emitConstant(unsigned Val, unsigned Size);
+
+ void emitBasicBlock(MachineBasicBlock &MBB);
+ void emitInstruction(MachineInstr &MI);
+
+ /// Function generated by the CodeEmitterGenerator using TableGen
+ ///
+ unsigned getBinaryCodeForInstr(MachineInstr &MI);
+ };
+ }
+
+ bool UltraSparc::addPassesToEmitMachineCode(PassManager &PM,
+ MachineCodeEmitter &MCE) {
+ //PM.add(new SparcV9CodeEmitter(MCE));
+ //MachineCodeEmitter *M = MachineCodeEmitter::createDebugMachineCodeEmitter();
+ MachineCodeEmitter *M =
+ MachineCodeEmitter::createFilePrinterMachineCodeEmitter();
+ PM.add(new SparcV9CodeEmitter(*M));
+ return false;
+ }
+
+ void SparcV9CodeEmitter::emitConstant(unsigned Val, unsigned Size) {
+ // Output the constant in big endian byte order...
+ unsigned byteVal;
+ for (int i = Size-1; i >= 0; --i) {
+ byteVal = Val >> 8*i;
+ MCE.emitByte(byteVal & 255);
+ }
+ }
+
+ int64_t SparcV9CodeEmitter::getMachineOpValue(MachineOperand &MO) {
+ if (MO.isPhysicalRegister()) {
+ return MO.getReg();
+ } else if (MO.isImmediate()) {
+ return MO.getImmedValue();
+ } else if (MO.isPCRelativeDisp()) {
+ // FIXME!!!
+ //return MO.getPCRelativeDisp();
+ return 0;
+ } else {
+ assert(0 && "Unknown type of MachineOperand");
+ return 0;
+ }
+ }
+
+ unsigned SparcV9CodeEmitter::getValueBit(int64_t Val, unsigned bit) {
+ Val >>= bit;
+ return (Val & 1);
+ }
+
+
+ bool SparcV9CodeEmitter::runOnMachineFunction(MachineFunction &MF) {
+ MCE.startFunction(MF);
+ MCE.emitConstantPool(MF.getConstantPool());
+ for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I)
+ emitBasicBlock(*I);
+ MCE.finishFunction(MF);
+ return false;
+ }
+
+ void SparcV9CodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
+ MCE.startBasicBlock(MBB);
+ for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I)
+ emitInstruction(**I);
+ }
+
+ void SparcV9CodeEmitter::emitInstruction(MachineInstr &MI) {
+ emitConstant(getBinaryCodeForInstr(MI), 4);
+ }
+
+ #include "SparcV9CodeEmitter.inc"
Index: llvm/lib/Target/Sparc/.cvsignore
diff -c /dev/null llvm/lib/Target/Sparc/.cvsignore:1.1
*** /dev/null Tue May 27 15:08:08 2003
--- llvm/lib/Target/Sparc/.cvsignore Tue May 27 15:07:58 2003
***************
*** 0 ****
--- 1 ----
+ SparcV9CodeEmitter.inc
Index: llvm/lib/Target/Sparc/Makefile
diff -u llvm/lib/Target/Sparc/Makefile:1.13 llvm/lib/Target/Sparc/Makefile:1.14
--- llvm/lib/Target/Sparc/Makefile:1.13 Mon Sep 23 08:12:28 2002
+++ llvm/lib/Target/Sparc/Makefile Tue May 27 15:07:58 2003
@@ -32,3 +32,6 @@
$(BUILD_ROOT)/Depend/Sparc.burm.d: $(BUILD_ROOT)/Depend/.dir
touch $@
+SparcV9CodeEmitter.inc: SparcV9.td
+ @echo "TableGen-erating $@"
+ cpp -P SparcV9.td | tblgen -gen-emitter > SparcV9CodeEmitter.inc
From lattner at cs.uiuc.edu Tue May 27 16:24:01 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Tue May 27 16:24:01 2003
Subject: [llvm-commits] CVS: llvm/tools/llc/Makefile llc.cpp
Message-ID: <200305272123.QAA00923@apoc.cs.uiuc.edu>
Changes in directory llvm/tools/llc:
Makefile updated: 1.34 -> 1.35
llc.cpp updated: 1.71 -> 1.72
---
Log message:
Remove ugly hack (that I put in originally) for building in trace stuff
automatically in LLC
---
Diffs of the changes:
Index: llvm/tools/llc/Makefile
diff -u llvm/tools/llc/Makefile:1.34 llvm/tools/llc/Makefile:1.35
--- llvm/tools/llc/Makefile:1.34 Sun Jan 19 15:55:43 2003
+++ llvm/tools/llc/Makefile Tue May 27 16:23:02 2003
@@ -9,11 +9,9 @@
preopts \
postopts.a \
target.a \
- instrument \
livevar \
- ipo.a \
- scalaropts.a \
transforms.a \
+ scalaropts.a \
analysis.a \
transformutils.a \
bcreader \
Index: llvm/tools/llc/llc.cpp
diff -u llvm/tools/llc/llc.cpp:1.71 llvm/tools/llc/llc.cpp:1.72
--- llvm/tools/llc/llc.cpp:1.71 Sun Apr 27 22:28:56 2003
+++ llvm/tools/llc/llc.cpp Tue May 27 16:23:02 2003
@@ -7,12 +7,8 @@
#include "llvm/Bytecode/Reader.h"
#include "llvm/Target/TargetMachineImpls.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Transforms/Scalar.h"
-#include "llvm/Transforms/Utils/Linker.h"
#include "llvm/Assembly/PrintModulePass.h"
-#include "llvm/Bytecode/WriteBytecodePass.h"
-#include "llvm/Transforms/IPO.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Pass.h"
@@ -57,16 +53,6 @@
DumpAsm("d", cl::desc("Print bytecode before native code generation"),
cl::Hidden);
-static cl::opt
-TraceLibPath("tracelibpath", cl::desc("Path to libinstr for trace code"),
- cl::value_desc("directory"), cl::Hidden);
-
-
-// flags set from -tracem and -trace options to control tracing
-static bool TraceFunctions = false;
-static bool TraceBasicBlocks = false;
-
-
// GetFileNameRoot - Helper function to get the basename of a filename...
static inline std::string
GetFileNameRoot(const std::string &InputFilename)
@@ -82,81 +68,6 @@
return outputFilename;
}
-static bool
-insertTraceCodeFor(Module &M)
-{
- PassManager Passes;
-
- // Insert trace code in all functions in the module
- if (TraceBasicBlocks)
- Passes.add(createTraceValuesPassForBasicBlocks());
- else if (TraceFunctions)
- Passes.add(createTraceValuesPassForFunction());
- else
- return false;
-
- // Eliminate duplication in constant pool
- Passes.add(createConstantMergePass());
-
- // Run passes to insert and clean up trace code...
- Passes.run(M);
-
- std::string ErrorMessage;
-
- // Load the module that contains the runtime helper routines neccesary for
- // pointer hashing and stuff... link this module into the program if possible
- //
- Module *TraceModule = ParseBytecodeFile(TraceLibPath+"libinstr.bc");
-
- // Check if the TraceLibPath contains a valid module. If not, try to load
- // the module from the current LLVM-GCC install directory. This is kindof
- // a hack, but allows people to not HAVE to have built the library.
- //
- if (TraceModule == 0)
- TraceModule = ParseBytecodeFile("/home/vadve/lattner/cvs/gcc_install/lib/"
- "gcc-lib/llvm/3.1/libinstr.bc");
-
- // If we still didn't get it, cancel trying to link it in...
- if (TraceModule == 0)
- std::cerr <<"WARNING: couldn't load trace routines to link into program!\n";
- else
- {
- // Link in the trace routines... if this fails, don't panic, because the
- // compile should still succeed, but the native linker will probably fail.
- //
- std::auto_ptr TraceRoutines(TraceModule);
- if (LinkModules(&M, TraceRoutines.get(), &ErrorMessage))
- std::cerr << "WARNING: Error linking in trace routines: "
- << ErrorMessage << "\n";
- }
-
- // Write out the module with tracing code just before code generation
- assert (InputFilename != "-"
- && "Cannot write out traced bytecode when reading input from stdin");
- std::string TraceFilename = GetFileNameRoot(InputFilename) + ".trace.bc";
-
- std::ofstream Out(TraceFilename.c_str());
- if (!Out.good())
- std::cerr << "Error opening '" << TraceFilename
- << "'!: Skipping output of trace code as bytecode\n";
- else
- {
- std::cerr << "Emitting trace code to '" << TraceFilename
- << "' for comparison...\n";
- WriteBytecodeToFile(&M, Out);
- }
-
- return true;
-}
-
-// Making tracing a module pass so the entire module with tracing
-// can be written out before continuing.
-struct InsertTracingCodePass: public Pass {
- virtual bool run(Module &M) {
- return insertTraceCodeFor(M);
- }
-};
-
//===---------------------------------------------------------------------===//
// Function main()
@@ -194,36 +105,27 @@
// Create a new optimization pass for each one specified on the command line
// Deal specially with tracing passes, which must be run differently than opt.
//
- for (unsigned i = 0; i < OptimizationList.size(); ++i)
- {
- const PassInfo *Opt = OptimizationList[i];
-
- if (std::string(Opt->getPassArgument()) == "trace")
- TraceFunctions = !(TraceBasicBlocks = true);
- else if (std::string(Opt->getPassArgument()) == "tracem")
- TraceFunctions = !(TraceBasicBlocks = false);
- else
- { // handle other passes as normal optimization passes
- if (Opt->getNormalCtor())
- Passes.add(Opt->getNormalCtor()());
- else if (Opt->getTargetCtor())
- Passes.add(Opt->getTargetCtor()(Target));
- else
- std::cerr << argv[0] << ": cannot create pass: "
- << Opt->getPassName() << "\n";
- }
- }
-
- // Run tracing passes after other optimization passes and before llc passes.
- if (TraceFunctions || TraceBasicBlocks)
- Passes.add(new InsertTracingCodePass);
+ for (unsigned i = 0; i < OptimizationList.size(); ++i) {
+ const PassInfo *Opt = OptimizationList[i];
+
+ // handle other passes as normal optimization passes
+ if (Opt->getNormalCtor())
+ Passes.add(Opt->getNormalCtor()());
+ else if (Opt->getTargetCtor())
+ Passes.add(Opt->getTargetCtor()(Target));
+ else
+ std::cerr << argv[0] << ": cannot create pass: "
+ << Opt->getPassName() << "\n";
+ }
// Decompose multi-dimensional refs into a sequence of 1D refs
+ // FIXME: This is sparc specific!
Passes.add(createDecomposeMultiDimRefsPass());
// Replace malloc and free instructions with library calls.
// Do this after tracing until lli implements these lib calls.
// For now, it will emulate malloc and free internally.
+ // FIXME: This is sparc specific!
Passes.add(createLowerAllocationsPass());
// If LLVM dumping after transformations is requested, add it to the pipeline
From lattner at cs.uiuc.edu Tue May 27 16:35:00 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Tue May 27 16:35:00 2003
Subject: [llvm-commits] CVS: llvm/test/Programs/SingleSource/mandel.c
Message-ID: <200305272134.QAA00996@apoc.cs.uiuc.edu>
Changes in directory llvm/test/Programs/SingleSource:
mandel.c (r1.1) removed
---
Log message:
Remove test until it can be fixed on sparc
---
Diffs of the changes:
From brukman at cs.uiuc.edu Tue May 27 16:41:00 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 16:41:00 2003
Subject: [llvm-commits] CVS: llvm/tools/lli/JIT/SparcEmitter.cpp Emitter.cpp JIT.cpp VM.h
Message-ID: <200305272140.QAA24901@zion.cs.uiuc.edu>
Changes in directory llvm/tools/lli/JIT:
SparcEmitter.cpp added (r1.1)
Emitter.cpp updated: 1.6 -> 1.7
JIT.cpp updated: 1.3 -> 1.4
VM.h updated: 1.5 -> 1.6
---
Log message:
Allow for specification of which JIT to run on the commandline.
`lli -march=x86' or `lli -march=sparc' will forcefully select the JIT even on a
different platform. Running lli without the -march option will select the JIT
for the platform that it's currently running on.
Pro: can test Sparc JIT (debug printing mode) on X86 -- faster to compile/link
LLVM source base to test changes.
Con: Linking lli on x86 now pulls in all the Sparc libs -> longer link time
(but X86 can bear it, right?)
In the future, perhaps this should be a ./configure option to enable/disable
target JITting...
---
Diffs of the changes:
Index: llvm/tools/lli/JIT/SparcEmitter.cpp
diff -c /dev/null llvm/tools/lli/JIT/SparcEmitter.cpp:1.1
*** /dev/null Tue May 27 16:40:49 2003
--- llvm/tools/lli/JIT/SparcEmitter.cpp Tue May 27 16:40:39 2003
***************
*** 0 ****
--- 1,218 ----
+ //===-- SparcEmitter.cpp - Write machine code to executable memory --------===//
+ //
+ // This file defines a MachineCodeEmitter object that is used by Jello to write
+ // machine code to memory and remember where relocatable values lie.
+ //
+ //===----------------------------------------------------------------------===//
+
+ #include "VM.h"
+ #include "llvm/CodeGen/MachineCodeEmitter.h"
+ #include "llvm/CodeGen/MachineFunction.h"
+ #include "llvm/CodeGen/MachineConstantPool.h"
+ #include "llvm/CodeGen/MachineInstr.h"
+ #include "llvm/Target/TargetData.h"
+ #include "llvm/Function.h"
+ #include "Support/Statistic.h"
+ // FIXME
+ #include "../../../lib/Target/Sparc/SparcV9CodeEmitter.h"
+
+ namespace {
+ Statistic<> NumBytes("jello", "Number of bytes of machine code compiled");
+
+ class SparcEmitter : public MachineCodeEmitter {
+ VM &TheVM;
+
+ unsigned char *CurBlock, *CurByte;
+
+ // When outputting a function stub in the context of some other function, we
+ // save CurBlock and CurByte here.
+ unsigned char *SavedCurBlock, *SavedCurByte;
+
+ std::vector > > BBRefs;
+ std::map BBLocations;
+ std::vector ConstantPoolAddresses;
+ public:
+ SparcEmitter(VM &vm) : TheVM(vm) {}
+
+ virtual void startFunction(MachineFunction &F);
+ virtual void finishFunction(MachineFunction &F);
+ virtual void emitConstantPool(MachineConstantPool *MCP);
+ virtual void startBasicBlock(MachineBasicBlock &BB);
+ virtual void startFunctionStub(const Function &F, unsigned StubSize);
+ virtual void* finishFunctionStub(const Function &F);
+ virtual void emitByte(unsigned char B);
+ virtual void emitPCRelativeDisp(Value *V);
+ virtual void emitGlobalAddress(GlobalValue *V, bool isPCRelative);
+ virtual void emitGlobalAddress(const std::string &Name, bool isPCRelative);
+ virtual void emitFunctionConstantValueAddress(unsigned ConstantNum,
+ int Offset);
+
+ virtual void saveBBreference(BasicBlock *BB, MachineInstr &MI);
+
+ private:
+ void emitAddress(void *Addr, bool isPCRelative);
+ };
+ }
+
+ MachineCodeEmitter *VM::createSparcEmitter(VM &V) {
+ return new SparcEmitter(V);
+ }
+
+
+ #define _POSIX_MAPPED_FILES
+ #include
+ #include
+
+ // FIXME: This should be rewritten to support a real memory manager for
+ // executable memory pages!
+ static void *getMemory(unsigned NumPages) {
+ return mmap(0, 4096*NumPages, PROT_READ|PROT_WRITE|PROT_EXEC,
+ MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
+ }
+
+
+ void SparcEmitter::startFunction(MachineFunction &F) {
+ CurBlock = (unsigned char *)getMemory(8);
+ CurByte = CurBlock; // Start writing at the beginning of the fn.
+ TheVM.addGlobalMapping(F.getFunction(), CurBlock);
+ }
+
+ void SparcEmitter::finishFunction(MachineFunction &F) {
+ ConstantPoolAddresses.clear();
+ for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) {
+ // Re-write branches to BasicBlocks for the entire function
+ unsigned Location = BBLocations[BBRefs[i].first];
+ unsigned *Ref = BBRefs[i].second.first;
+ MachineInstr *MI = BBRefs[i].second.second;
+ for (unsigned i=0, e = MI->getNumOperands(); i != e; ++i) {
+ MachineOperand &op = MI->getOperand(i);
+ if (op.isImmediate()) {
+ MI->SetMachineOperandConst(i, op.getType(), Location);
+ break;
+ }
+ }
+ unsigned fixedInstr = SparcV9CodeEmitter::getBinaryCodeForInstr(*MI);
+ *Ref = fixedInstr;
+ }
+ BBRefs.clear();
+ BBLocations.clear();
+
+ NumBytes += CurByte-CurBlock;
+
+ DEBUG(std::cerr << "Finished CodeGen of [0x" << std::hex
+ << (unsigned)(intptr_t)CurBlock
+ << std::dec << "] Function: " << F.getFunction()->getName()
+ << ": " << CurByte-CurBlock << " bytes of text\n");
+ }
+
+ void SparcEmitter::emitConstantPool(MachineConstantPool *MCP) {
+ const std::vector &Constants = MCP->getConstants();
+ for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
+ // For now we just allocate some memory on the heap, this can be
+ // dramatically improved.
+ const Type *Ty = ((Value*)Constants[i])->getType();
+ void *Addr = malloc(TheVM.getTargetData().getTypeSize(Ty));
+ TheVM.InitializeMemory(Constants[i], Addr);
+ ConstantPoolAddresses.push_back(Addr);
+ }
+ }
+
+
+ void SparcEmitter::startBasicBlock(MachineBasicBlock &BB) {
+ BBLocations[BB.getBasicBlock()] = (unsigned)(intptr_t)CurByte;
+ }
+
+
+ void SparcEmitter::startFunctionStub(const Function &F, unsigned StubSize) {
+ SavedCurBlock = CurBlock; SavedCurByte = CurByte;
+ // FIXME: this is a huge waste of memory.
+ CurBlock = (unsigned char *)getMemory((StubSize+4095)/4096);
+ CurByte = CurBlock; // Start writing at the beginning of the fn.
+ }
+
+ void *SparcEmitter::finishFunctionStub(const Function &F) {
+ NumBytes += CurByte-CurBlock;
+ DEBUG(std::cerr << "Finished CodeGen of [0x" << std::hex
+ << (unsigned)(intptr_t)CurBlock
+ << std::dec << "] Function stub for: " << F.getName()
+ << ": " << CurByte-CurBlock << " bytes of text\n");
+ std::swap(CurBlock, SavedCurBlock);
+ CurByte = SavedCurByte;
+ return SavedCurBlock;
+ }
+
+ void SparcEmitter::emitByte(unsigned char B) {
+ *CurByte++ = B; // Write the byte to memory
+ }
+
+ // BasicBlock -> pair
+ // when the BB is emitted, machineinstr is modified with then-currbyte,
+ // processed with MCE, and written out at memloc.
+ void SparcEmitter::saveBBreference(BasicBlock *BB, MachineInstr &MI) {
+ BBRefs.push_back(std::make_pair(BB, std::make_pair((unsigned*)CurByte, &MI)));
+ }
+
+
+ // emitPCRelativeDisp - For functions, just output a displacement that will
+ // cause a reference to the zero page, which will cause a seg-fault, causing
+ // things to get resolved on demand. Keep track of these markers.
+ //
+ // For basic block references, keep track of where the references are so they
+ // may be patched up when the basic block is defined.
+ //
+ // BasicBlock -> pair
+ // when the BB is emitted, machineinstr is modified with then-currbyte,
+ // processed with MCE, and written out at memloc.
+
+ void SparcEmitter::emitPCRelativeDisp(Value *V) {
+ #if 0
+ BasicBlock *BB = cast(V); // Keep track of reference...
+ BBRefs.push_back(std::make_pair(BB, (unsigned*)CurByte));
+ CurByte += 4;
+ #endif
+ }
+
+ // emitAddress - Emit an address in either direct or PCRelative form...
+ //
+ void SparcEmitter::emitAddress(void *Addr, bool isPCRelative) {
+ #if 0
+ if (isPCRelative) {
+ *(intptr_t*)CurByte = (intptr_t)Addr - (intptr_t)CurByte-4;
+ } else {
+ *(void**)CurByte = Addr;
+ }
+ CurByte += 4;
+ #endif
+ }
+
+ void SparcEmitter::emitGlobalAddress(GlobalValue *V, bool isPCRelative) {
+ if (isPCRelative) { // must be a call, this is a major hack!
+ // Try looking up the function to see if it is already compiled!
+ if (void *Addr = TheVM.getPointerToGlobalIfAvailable(V)) {
+ emitAddress(Addr, isPCRelative);
+ } else { // Function has not yet been code generated!
+ TheVM.addFunctionRef(CurByte, cast(V));
+
+ // Delayed resolution...
+ emitAddress((void*)VM::CompilationCallback, isPCRelative);
+ }
+ } else {
+ emitAddress(TheVM.getPointerToGlobal(V), isPCRelative);
+ }
+ }
+
+ void SparcEmitter::emitGlobalAddress(const std::string &Name, bool isPCRelative)
+ {
+ #if 0
+ emitAddress(TheVM.getPointerToNamedFunction(Name), isPCRelative);
+ #endif
+ }
+
+ void SparcEmitter::emitFunctionConstantValueAddress(unsigned ConstantNum,
+ int Offset) {
+ assert(ConstantNum < ConstantPoolAddresses.size() &&
+ "Invalid ConstantPoolIndex!");
+ *(void**)CurByte = (char*)ConstantPoolAddresses[ConstantNum]+Offset;
+ CurByte += 4;
+ }
Index: llvm/tools/lli/JIT/Emitter.cpp
diff -u llvm/tools/lli/JIT/Emitter.cpp:1.6 llvm/tools/lli/JIT/Emitter.cpp:1.7
--- llvm/tools/lli/JIT/Emitter.cpp:1.6 Thu May 8 22:30:07 2003
+++ llvm/tools/lli/JIT/Emitter.cpp Tue May 27 16:40:39 2003
@@ -48,7 +48,7 @@
};
}
-MachineCodeEmitter *VM::createEmitter(VM &V) {
+MachineCodeEmitter *VM::createX86Emitter(VM &V) {
return new Emitter(V);
}
Index: llvm/tools/lli/JIT/JIT.cpp
diff -u llvm/tools/lli/JIT/JIT.cpp:1.3 llvm/tools/lli/JIT/JIT.cpp:1.4
--- llvm/tools/lli/JIT/JIT.cpp:1.3 Wed May 14 08:53:40 2003
+++ llvm/tools/lli/JIT/JIT.cpp Tue May 27 16:40:39 2003
@@ -9,28 +9,65 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetMachineImpls.h"
#include "llvm/Module.h"
+#include "Support/CommandLine.h"
+
+namespace {
+ cl::opt
+ Arch("march", cl::desc("Architecture: `x86' or `sparc'"), cl::Prefix,
+ cl::value_desc("machine architecture"));
+
+ static std::string DefaultArch =
+#if defined(i386) || defined(__i386__) || defined(__x86__)
+ "x86";
+#elif defined(sparc) || defined(__sparc__) || defined(__sparcv9)
+ "sparc";
+#else
+ "";
+#endif
+
+}
/// createJIT - Create an return a new JIT compiler if there is one available
/// for the current target. Otherwise it returns null.
///
ExecutionEngine *ExecutionEngine::createJIT(Module *M, unsigned Config) {
- // FIXME: This should be controlled by which subdirectory gets linked in!
-#if !defined(i386) && !defined(__i386__) && !defined(__x86__)
- return 0;
-#endif
- // Allocate a target... in the future this will be controllable on the
- // command line.
- TargetMachine *Target = allocateX86TargetMachine(Config);
- assert(Target && "Could not allocate X86 target machine!");
+
+ TargetMachine* (*TargetMachineAllocator)(unsigned) = 0;
+ if (Arch == "")
+ Arch = DefaultArch;
- // Create the virtual machine object...
- return new VM(M, Target);
+ // Allow a command-line switch to override what *should* be the default target
+ // machine for this platform. This allows for debugging a Sparc JIT on X86 --
+ // our X86 machines are much faster at recompiling LLVM and linking lli.
+ if (Arch == "x86") {
+ TargetMachineAllocator = allocateX86TargetMachine;
+ } else if (Arch == "sparc") {
+ TargetMachineAllocator = allocateSparcTargetMachine;
+ }
+
+ if (TargetMachineAllocator) {
+ // Allocate a target...
+ TargetMachine *Target = (*TargetMachineAllocator)(Config);
+ assert(Target && "Could not allocate target machine!");
+
+ // Create the virtual machine object...
+ return new VM(M, Target);
+ } else {
+ return 0;
+ }
}
VM::VM(Module *M, TargetMachine *tm) : ExecutionEngine(M), TM(*tm) {
setTargetData(TM.getTargetData());
- MCE = createEmitter(*this); // Initialize MCE
+
+ // Initialize MCE
+ if (Arch == "x86") {
+ MCE = createX86Emitter(*this);
+ } else if (Arch == "sparc") {
+ MCE = createSparcEmitter(*this);
+ }
+
setupPassManager();
registerCallback();
emitGlobals();
Index: llvm/tools/lli/JIT/VM.h
diff -u llvm/tools/lli/JIT/VM.h:1.5 llvm/tools/lli/JIT/VM.h:1.6
--- llvm/tools/lli/JIT/VM.h:1.5 Wed May 14 08:53:40 2003
+++ llvm/tools/lli/JIT/VM.h Tue May 27 16:40:39 2003
@@ -62,7 +62,8 @@
static void runAtExitHandlers();
private:
- static MachineCodeEmitter *createEmitter(VM &V);
+ static MachineCodeEmitter *createX86Emitter(VM &V);
+ static MachineCodeEmitter *createSparcEmitter(VM &V);
void setupPassManager();
void *getPointerToFunction(const Function *F);
From brukman at cs.uiuc.edu Tue May 27 16:43:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 16:43:01 2003
Subject: [llvm-commits] CVS: llvm/tools/lli/Makefile
Message-ID: <200305272142.QAA24916@zion.cs.uiuc.edu>
Changes in directory llvm/tools/lli:
Makefile updated: 1.23 -> 1.24
---
Log message:
Link in Sparc libs for the JIT, even on X86 to be able to support debugging
of Sparc JIT (printing out instrs) on X86. Con: this increases linking time.
---
Diffs of the changes:
Index: llvm/tools/lli/Makefile
diff -u llvm/tools/lli/Makefile:1.23 llvm/tools/lli/Makefile:1.24
--- llvm/tools/lli/Makefile:1.23 Wed Apr 23 11:43:02 2003
+++ llvm/tools/lli/Makefile Tue May 27 16:42:05 2003
@@ -2,9 +2,25 @@
TOOLNAME = lli
PARALLEL_DIRS = Interpreter JIT
-JITLIBS = lli-jit codegen x86
-USEDLIBS = lli-interpreter $(JITLIBS) bcreader vmcore scalaropts.a \
- analysis.a support.a target.a
+# FIXME: This enables testing the Sparc JIT on x86.
+# Perhaps in the future this should be a ./configure option.
+
+# Generic JIT libraries
+JITLIBS = lli-jit codegen
+ARCHLIBS =
+
+# What the X86 JIT requires
+JITLIBS += x86
+ARCHLIBS +=
+
+# What the Sparc JIT requires
+JITLIBS += sparc
+ARCHLIBS = sched livevar instrument.a profpaths transformutils.a \
+ bcwriter transforms.a ipo.a ipa.a datastructure.a regalloc \
+ mapping select postopts.a preopts
+
+USEDLIBS = lli-interpreter $(JITLIBS) bcreader vmcore scalaropts \
+ analysis.a support.a target.a $(ARCHLIBS)
# Have gcc tell the linker to export symbols from the program so that
# dynamically loaded modules can be linked against them.
From lattner at cs.uiuc.edu Tue May 27 16:44:01 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Tue May 27 16:44:01 2003
Subject: [llvm-commits] CVS: llvm/test/Libraries/libinstr/Makefile tracelib.c
Message-ID: <200305272143.QAA01062@apoc.cs.uiuc.edu>
Changes in directory llvm/test/Libraries/libinstr:
Makefile updated: 1.2 -> 1.3
tracelib.c updated: 1.2 -> 1.3
---
Log message:
Update to match the reality that is now.
---
Diffs of the changes:
Index: llvm/test/Libraries/libinstr/Makefile
diff -u llvm/test/Libraries/libinstr/Makefile:1.2 llvm/test/Libraries/libinstr/Makefile:1.3
--- llvm/test/Libraries/libinstr/Makefile:1.2 Mon May 20 16:16:19 2002
+++ llvm/test/Libraries/libinstr/Makefile Tue May 27 16:43:14 2003
@@ -2,10 +2,5 @@
LIBNAME = instr
-# We use assert and memset here... and we are linked into the program AFTER final
-# link. Because of this, we have to play funny games here. :(
-LDFLAGS = /home/vadve/lattner/cvs/gcc_install/lib/gcc-lib/llvm/3.1/libgcc.bc \
- /home/vadve/lattner/cvs/gcc_install/lib/gcc-lib/llvm/3.1/libc.bc
-
include ../Makefile.libs
Index: llvm/test/Libraries/libinstr/tracelib.c
diff -u llvm/test/Libraries/libinstr/tracelib.c:1.2 llvm/test/Libraries/libinstr/tracelib.c:1.3
--- llvm/test/Libraries/libinstr/tracelib.c:1.2 Mon May 20 16:15:30 2002
+++ llvm/test/Libraries/libinstr/tracelib.c Tue May 27 16:43:14 2003
@@ -10,7 +10,7 @@
#include
#include
#include
-
+#include
/*===---------------------------------------------------------------------=====
* HASH FUNCTIONS
From brukman at cs.uiuc.edu Tue May 27 16:46:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 16:46:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcV9CodeEmitter.h SparcV9CodeEmitter.cpp
Message-ID: <200305272145.QAA25124@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
SparcV9CodeEmitter.h added (r1.1)
SparcV9CodeEmitter.cpp updated: 1.1 -> 1.2
---
Log message:
Broke out class definition from SparcV9CodeEmitter, and added ability to take a
MachineCodeEmitter to make a pass-through debugger -- output to memory and to
std::cerr.
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/SparcV9CodeEmitter.h
diff -c /dev/null llvm/lib/Target/Sparc/SparcV9CodeEmitter.h:1.1
*** /dev/null Tue May 27 16:45:15 2003
--- llvm/lib/Target/Sparc/SparcV9CodeEmitter.h Tue May 27 16:45:05 2003
***************
*** 0 ****
--- 1,33 ----
+
+
+ #ifndef SPARCV9CODEEMITTER_H
+ #define SPARCV9CODEEMITTER_H
+
+ #include "llvm/CodeGen/MachineCodeEmitter.h"
+ #include "llvm/CodeGen/MachineFunctionPass.h"
+ #include "llvm/CodeGen/MachineInstr.h"
+
+ class SparcV9CodeEmitter : public MachineFunctionPass {
+ MachineCodeEmitter &MCE;
+
+ public:
+ SparcV9CodeEmitter(MachineCodeEmitter &M) : MCE(M) {}
+
+ bool runOnMachineFunction(MachineFunction &F);
+
+ /// Function generated by the CodeEmitterGenerator using TableGen
+ ///
+ static unsigned getBinaryCodeForInstr(MachineInstr &MI);
+
+ private:
+ static int64_t getMachineOpValue(MachineOperand &MO);
+ static unsigned getValueBit(int64_t Val, unsigned bit);
+
+ void emitConstant(unsigned Val, unsigned Size);
+
+ void emitBasicBlock(MachineBasicBlock &MBB);
+ void emitInstruction(MachineInstr &MI);
+
+ };
+
+ #endif
Index: llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp
diff -u llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.1 llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.2
--- llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.1 Tue May 27 15:07:58 2003
+++ llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp Tue May 27 16:45:05 2003
@@ -3,37 +3,14 @@
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "SparcInternals.h"
-
-namespace {
- class SparcV9CodeEmitter : public MachineFunctionPass {
- MachineCodeEmitter &MCE;
-
- public:
- SparcV9CodeEmitter(MachineCodeEmitter &M) : MCE(M) {}
-
- bool runOnMachineFunction(MachineFunction &F);
-
- private:
- int64_t getMachineOpValue(MachineOperand &MO);
- unsigned getValueBit(int64_t Val, unsigned bit);
-
- void emitConstant(unsigned Val, unsigned Size);
-
- void emitBasicBlock(MachineBasicBlock &MBB);
- void emitInstruction(MachineInstr &MI);
-
- /// Function generated by the CodeEmitterGenerator using TableGen
- ///
- unsigned getBinaryCodeForInstr(MachineInstr &MI);
- };
-}
+#include "SparcV9CodeEmitter.h"
bool UltraSparc::addPassesToEmitMachineCode(PassManager &PM,
MachineCodeEmitter &MCE) {
//PM.add(new SparcV9CodeEmitter(MCE));
//MachineCodeEmitter *M = MachineCodeEmitter::createDebugMachineCodeEmitter();
MachineCodeEmitter *M =
- MachineCodeEmitter::createFilePrinterMachineCodeEmitter();
+ MachineCodeEmitter::createFilePrinterMachineCodeEmitter(MCE);
PM.add(new SparcV9CodeEmitter(*M));
return false;
}
From brukman at cs.uiuc.edu Tue May 27 16:47:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 16:47:01 2003
Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetMachineImpls.h
Message-ID: <200305272146.QAA25140@zion.cs.uiuc.edu>
Changes in directory llvm/include/llvm/Target:
TargetMachineImpls.h updated: 1.3 -> 1.4
---
Log message:
Allow allocation of a Sparc TargetMachine.
---
Diffs of the changes:
Index: llvm/include/llvm/Target/TargetMachineImpls.h
diff -u llvm/include/llvm/Target/TargetMachineImpls.h:1.3 llvm/include/llvm/Target/TargetMachineImpls.h:1.4
--- llvm/include/llvm/Target/TargetMachineImpls.h:1.3 Mon Dec 23 18:02:17 2002
+++ llvm/include/llvm/Target/TargetMachineImpls.h Tue May 27 16:46:07 2003
@@ -25,7 +25,8 @@
// allocateSparcTargetMachine - Allocate and return a subclass of TargetMachine
// that implements the Sparc backend.
//
-TargetMachine *allocateSparcTargetMachine();
+TargetMachine *allocateSparcTargetMachine(unsigned Configuration =
+ TM::PtrSize64|TM::BigEndian);
// allocateX86TargetMachine - Allocate and return a subclass of TargetMachine
// that implements the X86 backend. The X86 target machine can run in
@@ -33,6 +34,6 @@
// size and different endianness if desired.
//
TargetMachine *allocateX86TargetMachine(unsigned Configuration =
- TM::PtrSize32|TM::LittleEndian);
+ TM::PtrSize32|TM::LittleEndian);
#endif
From brukman at cs.uiuc.edu Tue May 27 16:48:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 16:48:01 2003
Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineCodeEmitter.h
Message-ID: <200305272147.QAA25163@zion.cs.uiuc.edu>
Changes in directory llvm/include/llvm/CodeGen:
MachineCodeEmitter.h updated: 1.9 -> 1.10
---
Log message:
Defines a pass-through debugging emitter -- it writes to a file for inspection
and to memory to test execution (using a passed-in code emitter).
---
Diffs of the changes:
Index: llvm/include/llvm/CodeGen/MachineCodeEmitter.h
diff -u llvm/include/llvm/CodeGen/MachineCodeEmitter.h:1.9 llvm/include/llvm/CodeGen/MachineCodeEmitter.h:1.10
--- llvm/include/llvm/CodeGen/MachineCodeEmitter.h:1.9 Thu May 8 22:27:28 2003
+++ llvm/include/llvm/CodeGen/MachineCodeEmitter.h Tue May 27 16:46:56 2003
@@ -84,6 +84,13 @@
/// can be used for debugging users of the MachineCodeEmitter interface.
///
static MachineCodeEmitter *createDebugMachineCodeEmitter();
+
+ /// createFilePrinterMachineCodeEmitter - Return a dynamically allocated
+ /// machine code emitter, which prints binary code to a file. This
+ /// can be used for debugging users of the MachineCodeEmitter interface.
+ ///
+ static MachineCodeEmitter*
+ createFilePrinterMachineCodeEmitter(MachineCodeEmitter&);
};
#endif
From brukman at cs.uiuc.edu Tue May 27 17:02:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 17:02:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInternals.h
Message-ID: <200305272201.RAA26532@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
SparcInternals.h updated: 1.85 -> 1.86
---
Log message:
Add prototypes to add passes to JIT compilation and code emission.
Also, added annotations to how instructions are modified (reg/imm operands).
Added prototype for adding register numbers to values pass for interfacing with
the target-independent register allocators in the JIT.
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/SparcInternals.h
diff -u llvm/lib/Target/Sparc/SparcInternals.h:1.85 llvm/lib/Target/Sparc/SparcInternals.h:1.86
--- llvm/lib/Target/Sparc/SparcInternals.h:1.85 Mon May 26 19:02:22 2003
+++ llvm/lib/Target/Sparc/SparcInternals.h Tue May 27 17:01:10 2003
@@ -90,14 +90,14 @@
bool ignore;
if (this->maxImmedConstant(opCode, ignore) != 0) {
// 1st store opcode
- assert(! this->isStore((MachineOpCode) V9::STB - 1));
+ assert(! this->isStore((MachineOpCode) V9::STB - 1)); //r
// last store opcode
- assert(! this->isStore((MachineOpCode) V9::STXFSR + 1));
+ assert(! this->isStore((MachineOpCode) V9::STXFSR + 1)); //i
if (opCode == V9::SETSW || opCode == V9::SETUW ||
opCode == V9::SETX || opCode == V9::SETHI)
return 0;
- if (opCode >= V9::STB && opCode <= V9::STXFSR)
+ if (opCode >= V9::STB && opCode <= V9::STXFSR) //r, i
return 2;
return 1;
}
@@ -107,10 +107,10 @@
/// createNOPinstr - returns the target's implementation of NOP, which is
/// usually a pseudo-instruction, implemented by a degenerate version of
- /// another instruction, e.g. X86: xchg ax, ax; SparcV9: sethi g0, 0
+ /// another instruction, e.g. X86: xchg ax, ax; SparcV9: sethi 0, g0
///
MachineInstr* createNOPinstr() const {
- return BuildMI(V9::SETHI, 2).addReg(SparcIntRegClass::g0).addZImm(0);
+ return BuildMI(V9::SETHI, 2).addZImm(0).addReg(SparcIntRegClass::g0);
}
/// isNOPinstr - not having a special NOP opcode, we need to know if a given
@@ -121,9 +121,9 @@
// Make sure the instruction is EXACTLY `sethi g0, 0'
if (MI.getOpcode() == V9::SETHI && MI.getNumOperands() == 2) {
const MachineOperand &op0 = MI.getOperand(0), &op1 = MI.getOperand(1);
- if (op0.isMachineRegister() &&
- op0.getMachineRegNum() == SparcIntRegClass::g0 &&
- op1.isImmediate() && op1.getImmedValue() == 0)
+ if (op0.isImmediate() && op0.getImmedValue() == 0 &&
+ op1.isMachineRegister() &&
+ op1.getMachineRegNum() == SparcIntRegClass::g0)
{
return true;
}
@@ -688,6 +688,12 @@
virtual bool IsUselessCopy (const MachineInstr* MI) const;
};
+/// createAddRegNumToValuesPass - this pass adds unsigned register numbers to
+/// instructions, since that's not done by the Sparc InstSelector, but that's
+/// how the target-independent register allocator in the JIT likes to see
+/// instructions. This pass enables the usage of the JIT register allocator(s).
+Pass *createAddRegNumToValuesPass();
+
//---------------------------------------------------------------------------
// class UltraSparcMachine
//
@@ -716,6 +722,9 @@
virtual const TargetOptInfo &getOptInfo() const { return optInfo; }
virtual bool addPassesToEmitAssembly(PassManager &PM, std::ostream &Out);
+ virtual bool addPassesToJITCompile(PassManager &PM);
+ virtual bool addPassesToEmitMachineCode(PassManager &PM,
+ MachineCodeEmitter &MCE);
// getPrologEpilogInsertionPass - Inserts prolog/epilog code.
Pass* getPrologEpilogInsertionPass();
From brukman at cs.uiuc.edu Tue May 27 17:05:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 17:05:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/Makefile
Message-ID: <200305272204.RAA27387@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
Makefile updated: 1.14 -> 1.15
---
Log message:
Moved generation of the SparcV9CodeEmitter.inc file higher in the Makefile so
that Makefile.common would see it.
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/Makefile
diff -u llvm/lib/Target/Sparc/Makefile:1.14 llvm/lib/Target/Sparc/Makefile:1.15
--- llvm/lib/Target/Sparc/Makefile:1.14 Tue May 27 15:07:58 2003
+++ llvm/lib/Target/Sparc/Makefile Tue May 27 17:04:38 2003
@@ -3,6 +3,10 @@
ExtraSource = Debug/Sparc.burm.cpp
+SparcV9CodeEmitter.inc: SparcV9.td
+ @echo "TableGen-erating $@"
+ cpp -P SparcV9.td | tblgen -gen-emitter > SparcV9CodeEmitter.inc
+
include $(LEVEL)/Makefile.common
ifdef ENABLE_OPTIMIZED
@@ -32,6 +36,3 @@
$(BUILD_ROOT)/Depend/Sparc.burm.d: $(BUILD_ROOT)/Depend/.dir
touch $@
-SparcV9CodeEmitter.inc: SparcV9.td
- @echo "TableGen-erating $@"
- cpp -P SparcV9.td | tblgen -gen-emitter > SparcV9CodeEmitter.inc
From brukman at cs.uiuc.edu Tue May 27 17:21:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 17:21:01 2003
Subject: [llvm-commits] CVS: llvm/utils/TableGen/CodeEmitterGen.cpp
Message-ID: <200305272220.RAA30394@zion.cs.uiuc.edu>
Changes in directory llvm/utils/TableGen:
CodeEmitterGen.cpp updated: 1.1 -> 1.2
---
Log message:
* Now outputting a static function getBinaryCodeForInstr() (JIT-accessible)
* For debugging purposes:
+ output the predefined bit pattern of the instruction
* Fixed inefficiency: only load an operand from MachineInstr once
* Bug fix: did not advance bit index when seeing named bit-fields "annul", "cc"
and "predict"
* Added a catch-all for non-supported instructions at the end of switch stmt.
---
Diffs of the changes:
Index: llvm/utils/TableGen/CodeEmitterGen.cpp
diff -u llvm/utils/TableGen/CodeEmitterGen.cpp:1.1 llvm/utils/TableGen/CodeEmitterGen.cpp:1.2
--- llvm/utils/TableGen/CodeEmitterGen.cpp:1.1 Fri May 23 19:15:53 2003
+++ llvm/utils/TableGen/CodeEmitterGen.cpp Tue May 27 17:19:58 2003
@@ -18,9 +18,10 @@
std::string ClassName = "SparcV9CodeEmitter::";
//const std::string &Namespace = Inst->getValue("Namespace")->getName();
- o << "unsigned " << ClassName
+ o << "static unsigned " << ClassName
<< "getBinaryCodeForInstr(MachineInstr &MI) {\n"
<< " unsigned Value = 0;\n"
+ << " std::cerr << MI;\n"
<< " switch (MI.getOpcode()) {\n";
for (std::vector::iterator I = Insts.begin(), E = Insts.end();
I != E; ++I)
@@ -38,18 +39,25 @@
unsigned Value = 0;
const std::vector &Vals = R->getValues();
+ o << " // prefilling: ";
// Start by filling in fixed values...
- for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
- if (BitInit *B = dynamic_cast(BI->getBit(i)))
- Value |= B->getValue() << i;
+ for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) {
+ if (BitInit *B = dynamic_cast(BI->getBit(e-i-1))) {
+ Value |= B->getValue() << (e-i-1);
+ o << B->getValue();
+ } else {
+ o << "0";
+ }
+ }
+ o << "\n\n";
- o << " Value = " << Value << "U;\n";
- o << " // " << *InstVal << "\n";
+ o << " // " << *InstVal << "\n\n";
+ o << " Value = " << Value << "U;\n\n";
// Loop over all of the fields in the instruction adding in any
// contributions to this value (due to bit references).
//
- unsigned Offset = 31, opNum=0;
+ unsigned op = 0;
std::map OpOrder;
for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
if (Vals[i].getName() != "Inst" &&
@@ -58,11 +66,15 @@
Vals[i].getName() != "cc" &&
Vals[i].getName() != "predict")
{
- o << " // " << opNum << ": " << Vals[i].getName() << "\n";
- OpOrder[Vals[i].getName()] = opNum++;
+ o << " // op" << op << ": " << Vals[i].getName() << "\n"
+ << " int64_t op" << op
+ <<" = getMachineOpValue(MI.getOperand("<= 0; --f) {
if (Vals[f].getPrefix()) {
BitsInit *FieldInitializer = (BitsInit*)Vals[f].getValue();
@@ -70,7 +82,6 @@
// Scan through the field looking for bit initializers of the current
// variable...
for (int i = FieldInitializer->getNumBits()-1; i >= 0; --i) {
-
if (BitInit *BI=dynamic_cast(FieldInitializer->getBit(i))){
--Offset;
} else if (UnsetInit *UI =
@@ -80,26 +91,32 @@
dynamic_cast(FieldInitializer->getBit(i))) {
TypedInit *TI = VBI->getVariable();
if (VarInit *VI = dynamic_cast(TI)) {
- o << " Value |= getValueBit(MI.getOperand("
- << OpOrder[VI->getName()]
- << "), " << VBI->getBitNum()
+ o << " Value |= getValueBit(op" << OpOrder[VI->getName()]
+ << ", " << VBI->getBitNum()
<< ")" << " << " << Offset << ";\n";
--Offset;
} else if (FieldInit *FI = dynamic_cast(TI)) {
// FIXME: implement this!
o << "FIELD INIT not implemented yet!\n";
} else {
- o << "something else\n";
+ o << "Error: UNIMPLEMENTED\n";
}
}
- }
+ }
+ } else {
+ if (Vals[f].getName() == "annul" || Vals[f].getName() == "cc" ||
+ Vals[f].getName() == "predict")
+ --Offset;
}
}
o << " break;\n"
<< " }\n";
}
- o << " }\n"
+ o << " default:\n"
+ << " std::cerr << \"Not supported instr: \" << MI << \"\\n\";\n"
+ << " abort();\n"
+ << " }\n"
<< " return Value;\n"
<< "}\n";
}
From brukman at cs.uiuc.edu Tue May 27 17:25:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 17:25:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/Sparc.cpp
Message-ID: <200305272224.RAA30613@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
Sparc.cpp updated: 1.62 -> 1.63
---
Log message:
* Allow passing in an unsigned configuration to allocateSparcTargetMachine()
a default value is set in the header file.
* Fixed some code layout to make it more consistent with the rest of codebase
* Added addPassesToJITCompile() with relevant passes
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/Sparc.cpp
diff -u llvm/lib/Target/Sparc/Sparc.cpp:1.62 llvm/lib/Target/Sparc/Sparc.cpp:1.63
--- llvm/lib/Target/Sparc/Sparc.cpp:1.62 Sat Apr 26 15:11:01 2003
+++ llvm/lib/Target/Sparc/Sparc.cpp Tue May 27 17:24:48 2003
@@ -53,9 +53,9 @@
// that implements the Sparc backend. (the llvm/CodeGen/Sparc.h interface)
//----------------------------------------------------------------------------
-TargetMachine *allocateSparcTargetMachine() { return new UltraSparc(); }
-
-
+TargetMachine *allocateSparcTargetMachine(unsigned Configuration) {
+ return new UltraSparc();
+}
//---------------------------------------------------------------------------
// class UltraSparcFrameInfo
@@ -155,13 +155,12 @@
// Specialize LLVM code for this target machine and then
// run basic dataflow optimizations on LLVM code.
- if (!DisablePreSelect)
- {
- PM.add(createPreSelectionPass(*this));
- PM.add(createReassociatePass());
- PM.add(createLICMPass());
- PM.add(createGCSEPass());
- }
+ if (!DisablePreSelect) {
+ PM.add(createPreSelectionPass(*this));
+ PM.add(createReassociatePass());
+ PM.add(createLICMPass());
+ PM.add(createGCSEPass());
+ }
PM.add(createInstructionSelectionPass(*this));
@@ -193,4 +192,30 @@
PM.add(getEmitBytecodeToAsmPass(Out));
PM.add(getFunctionInfo(Out));
return false;
+}
+
+// addPassesToJITCompile - This method controls the JIT method of code
+// generation for the UltraSparc.
+//
+bool UltraSparc::addPassesToJITCompile(PassManager &PM) {
+ // FIXME: implement the switch instruction in the instruction selector.
+ PM.add(createLowerSwitchPass());
+
+ // Construct and initialize the MachineFunction object for this fn.
+ PM.add(createMachineCodeConstructionPass(*this));
+
+ //Insert empty stackslots in the stack frame of each function
+ //so %fp+offset-8 and %fp+offset-16 are empty slots now!
+ PM.add(createStackSlotsPass(*this));
+
+ PM.add(createInstructionSelectionPass(*this));
+
+ // new pass: convert Value* in MachineOperand to an unsigned register
+ // this brings it in line with what the X86 JIT's RegisterAllocator expects
+ //PM.add(createAddRegNumToValuesPass());
+
+ PM.add(getRegisterAllocator(*this));
+ PM.add(getPrologEpilogInsertionPass());
+
+ return false; // success!
}
From brukman at cs.uiuc.edu Tue May 27 17:30:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 17:30:01 2003
Subject: [llvm-commits] CVS: llvm/utils/TableGen/CodeEmitterGen.cpp
Message-ID: <200305272229.RAA31228@zion.cs.uiuc.edu>
Changes in directory llvm/utils/TableGen:
CodeEmitterGen.cpp updated: 1.2 -> 1.3
---
Log message:
Cannot output `static' in generated cpp code: results in error. It's already
specified as a static member in class definition.
---
Diffs of the changes:
Index: llvm/utils/TableGen/CodeEmitterGen.cpp
diff -u llvm/utils/TableGen/CodeEmitterGen.cpp:1.2 llvm/utils/TableGen/CodeEmitterGen.cpp:1.3
--- llvm/utils/TableGen/CodeEmitterGen.cpp:1.2 Tue May 27 17:19:58 2003
+++ llvm/utils/TableGen/CodeEmitterGen.cpp Tue May 27 17:29:02 2003
@@ -18,7 +18,7 @@
std::string ClassName = "SparcV9CodeEmitter::";
//const std::string &Namespace = Inst->getValue("Namespace")->getName();
- o << "static unsigned " << ClassName
+ o << "unsigned " << ClassName
<< "getBinaryCodeForInstr(MachineInstr &MI) {\n"
<< " unsigned Value = 0;\n"
<< " std::cerr << MI;\n"
From brukman at cs.uiuc.edu Tue May 27 17:33:00 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 17:33:00 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInstr.def
Message-ID: <200305272232.RAA31250@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
SparcInstr.def updated: 1.15 -> 1.16
---
Log message:
One of the first major changes to make the work of JITting easier: adding
annotations on instructions to specify which format they are (i.e., do they take
2 registers and 1 immediate or just 3 registers) as that changes their binary
representation and hence, code emission.
This makes instructions more like how X86 defines them to be. Now, writers of
instruction selection must choose the correct opcode based on what instruction
type they are building, which they already know. Thus, the JIT doesn't have to
do the same work by `discovering' which operands an instruction really has.
As this involves lots of small changes to a lot of files in lib/target/Sparc,
I'll commit them individually because otherwise the diffs will be unreadable.
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/SparcInstr.def
diff -u llvm/lib/Target/Sparc/SparcInstr.def:1.15 llvm/lib/Target/Sparc/SparcInstr.def:1.16
--- llvm/lib/Target/Sparc/SparcInstr.def:1.15 Tue Jan 14 15:59:15 2003
+++ llvm/lib/Target/Sparc/SparcInstr.def Tue May 27 17:32:38 2003
@@ -52,22 +52,33 @@
I(SETHI, "sethi", 2, 1, B22, false, 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG | M_ARITH_FLAG)
// Add or add with carry.
-I(ADD , "add", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG)
-I(ADDcc , "addcc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_ARITH_FLAG | M_CC_FLAG )
-I(ADDC , "addc", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG)
-I(ADDCcc, "addccc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_ARITH_FLAG | M_CC_FLAG )
+I(ADDr , "add", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG)
+I(ADDi , "add", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG)
+I(ADDccr, "addcc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_ARITH_FLAG | M_CC_FLAG )
+I(ADDcci, "addcc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_ARITH_FLAG | M_CC_FLAG )
+I(ADDCr , "addc", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG)
+I(ADDCi , "addc", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG)
+I(ADDCccr, "addccc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_ARITH_FLAG | M_CC_FLAG )
+I(ADDCcci, "addccc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_ARITH_FLAG | M_CC_FLAG )
// Subtract or subtract with carry.
-I(SUB , "sub", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG)
-I(SUBcc , "subcc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_ARITH_FLAG | M_CC_FLAG )
-I(SUBC , "subc", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG)
-I(SUBCcc, "subccc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_ARITH_FLAG | M_CC_FLAG )
+I(SUBr , "sub", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG)
+I(SUBi , "sub", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG)
+I(SUBccr , "subcc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_ARITH_FLAG | M_CC_FLAG )
+I(SUBcci , "subcc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_ARITH_FLAG | M_CC_FLAG )
+I(SUBCr , "subc", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG)
+I(SUBCi , "subc", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG)
+I(SUBCccr, "subccc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_ARITH_FLAG | M_CC_FLAG )
+I(SUBCcci, "subccc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_ARITH_FLAG | M_CC_FLAG )
// Integer multiply, signed divide, unsigned divide.
// Note that the deprecated 32-bit multiply and multiply-step are not used.
-I(MULX , "mulx", 3, 2, B12, true , 0, 3, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG)
-I(SDIVX, "sdivx", 3, 2, B12, true , 0, 6, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG)
-I(UDIVX, "udivx", 3, 2, B12, true , 0, 6, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG)
+I(MULXr , "mulx", 3, 2, B12, true , 0, 3, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG)
+I(MULXi , "mulx", 3, 2, B12, true , 0, 3, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG)
+I(SDIVXr, "sdivx", 3, 2, B12, true , 0, 6, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG)
+I(SDIVXi, "sdivx", 3, 2, B12, true , 0, 6, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG)
+I(UDIVXr, "udivx", 3, 2, B12, true , 0, 6, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG)
+I(UDIVXi, "udivx", 3, 2, B12, true , 0, 6, SPARC_IEUN, M_INT_FLAG | M_ARITH_FLAG)
// Floating point add, subtract, compare.
// Note that destination of FCMP* instructions is operand 0, not operand 2.
@@ -96,26 +107,48 @@
I(FSQRTQ, "fsqrtq", 3, 2, 0, false, 0, 0, SPARC_FPM, M_FLOAT_FLAG | M_ARITH_FLAG)
// Logical operations
-I(AND , "and", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG)
-I(ANDcc , "andcc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_LOGICAL_FLAG)
-I(ANDN , "andn", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG)
-I(ANDNcc, "andncc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_LOGICAL_FLAG)
-I(OR , "or", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG)
-I(ORcc , "orcc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_LOGICAL_FLAG)
-I(ORN , "orn", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG)
-I(ORNcc , "orncc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_LOGICAL_FLAG)
-I(XOR , "xor", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG)
-I(XORcc , "xorcc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_LOGICAL_FLAG)
-I(XNOR , "xnor", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG)
-I(XNORcc, "xnorcc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_LOGICAL_FLAG)
+I(ANDr , "and", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG)
+I(ANDi , "and", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG)
+I(ANDccr , "andcc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_LOGICAL_FLAG)
+I(ANDcci , "andcc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_LOGICAL_FLAG)
+I(ANDNr , "andn", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG)
+I(ANDNi , "andn", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG)
+I(ANDNccr, "andncc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_LOGICAL_FLAG)
+I(ANDNcci, "andncc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_LOGICAL_FLAG)
+
+I(ORr , "or", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG)
+I(ORi , "or", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG)
+I(ORccr , "orcc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_LOGICAL_FLAG)
+I(ORcci , "orcc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_LOGICAL_FLAG)
+I(ORNr , "orn", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG)
+I(ORNi , "orn", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG)
+I(ORNccr, "orncc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_LOGICAL_FLAG)
+I(ORNcci, "orncc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_LOGICAL_FLAG)
+
+I(XORr , "xor", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG)
+I(XORi , "xor", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG)
+I(XORccr , "xorcc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_LOGICAL_FLAG)
+I(XORcci , "xorcc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_LOGICAL_FLAG)
+I(XNORr , "xnor", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG)
+I(XNORi , "xnor", 3, 2, B12, true , 0, 1, SPARC_IEUN, M_INT_FLAG | M_LOGICAL_FLAG)
+I(XNORccr, "xnorcc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_LOGICAL_FLAG)
+I(XNORcci, "xnorcc", 4, 2, B12, true , 0, 1, SPARC_IEU1, M_INT_FLAG | M_LOGICAL_FLAG)
// Shift operations
-I(SLL , "sll", 3, 2, B5, true , 0, 1, SPARC_IEU0, M_INT_FLAG | M_LOGICAL_FLAG)
-I(SRL , "srl", 3, 2, B5, true , 0, 1, SPARC_IEU0, M_INT_FLAG | M_LOGICAL_FLAG)
-I(SRA , "sra", 3, 2, B5, true , 0, 1, SPARC_IEU0, M_INT_FLAG | M_ARITH_FLAG)
-I(SLLX, "sllx", 3, 2, B6, true , 0, 1, SPARC_IEU0, M_INT_FLAG | M_LOGICAL_FLAG)
-I(SRLX, "srlx", 3, 2, B6, true , 0, 1, SPARC_IEU0, M_INT_FLAG | M_LOGICAL_FLAG)
-I(SRAX, "srax", 3, 2, B6, true , 0, 1, SPARC_IEU0, M_INT_FLAG | M_ARITH_FLAG)
+I(SLLr6 , "sll", 3, 2, B5, true , 0, 1, SPARC_IEU0, M_INT_FLAG | M_LOGICAL_FLAG)
+I(SRLr6 , "srl", 3, 2, B5, true , 0, 1, SPARC_IEU0, M_INT_FLAG | M_LOGICAL_FLAG)
+I(SRAr6 , "sra", 3, 2, B5, true , 0, 1, SPARC_IEU0, M_INT_FLAG | M_ARITH_FLAG)
+I(SLLXr6, "sllx", 3, 2, B6, true , 0, 1, SPARC_IEU0, M_INT_FLAG | M_LOGICAL_FLAG)
+I(SRLXr6, "srlx", 3, 2, B6, true , 0, 1, SPARC_IEU0, M_INT_FLAG | M_LOGICAL_FLAG)
+I(SRAXr6, "srax", 3, 2, B6, true , 0, 1, SPARC_IEU0, M_INT_FLAG | M_ARITH_FLAG)
+
+I(SLLi6 , "sll", 3, 2, B5, true , 0, 1, SPARC_IEU0, M_INT_FLAG | M_LOGICAL_FLAG)
+I(SRLi6 , "srl", 3, 2, B5, true , 0, 1, SPARC_IEU0, M_INT_FLAG | M_LOGICAL_FLAG)
+I(SRAi6 , "sra", 3, 2, B5, true , 0, 1, SPARC_IEU0, M_INT_FLAG | M_ARITH_FLAG)
+I(SLLXi6, "sllx", 3, 2, B6, true , 0, 1, SPARC_IEU0, M_INT_FLAG | M_LOGICAL_FLAG)
+I(SRLXi6, "srlx", 3, 2, B6, true , 0, 1, SPARC_IEU0, M_INT_FLAG | M_LOGICAL_FLAG)
+I(SRAXi6, "srax", 3, 2, B6, true , 0, 1, SPARC_IEU0, M_INT_FLAG | M_ARITH_FLAG)
+
// Floating point move, negate, and abs instructions
I(FMOVS, "fmovs", 2, 1, 0, false, 0, 1, SPARC_FPA, M_FLOAT_FLAG)
@@ -388,47 +421,72 @@
// Not reflected here: After a 3-cycle loads, all subsequent consecutive
// loads also require 3 cycles to avoid contention for the load return
// stage. Latency returns to 2 cycles after the first cycle with no load.
-I(LDSB, "ldsb", 3, 2, B12, true , 0, 6, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG)
-I(LDSH, "ldsh", 3, 2, B12, true , 0, 6, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG)
-I(LDSW, "ldsw", 3, 2, B12, true , 0, 6, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG)
-I(LDUB, "ldub", 3, 2, B12, true , 0, 5, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG)
-I(LDUH, "lduh", 3, 2, B12, true , 0, 5, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG)
-I(LDUW, "lduw", 3, 2, B12, true , 0, 5, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG)
-I(LDX , "ldx", 3, 2, B12, true , 0, 5, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG)
+I(LDSBr, "ldsb", 3, 2, B12, true , 0, 6, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG)
+I(LDSBi, "ldsb", 3, 2, B12, true , 0, 6, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG)
+I(LDSHr, "ldsh", 3, 2, B12, true , 0, 6, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG)
+I(LDSHi, "ldsh", 3, 2, B12, true , 0, 6, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG)
+I(LDSWr, "ldsw", 3, 2, B12, true , 0, 6, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG)
+I(LDSWi, "ldsw", 3, 2, B12, true , 0, 6, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG)
+I(LDUBr, "ldub", 3, 2, B12, true , 0, 5, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG)
+I(LDUBi, "ldub", 3, 2, B12, true , 0, 5, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG)
+I(LDUHr, "lduh", 3, 2, B12, true , 0, 5, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG)
+I(LDUHi, "lduh", 3, 2, B12, true , 0, 5, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG)
+I(LDUWr, "lduw", 3, 2, B12, true , 0, 5, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG)
+I(LDUWi, "lduw", 3, 2, B12, true , 0, 5, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG)
+I(LDXr , "ldx" , 3, 2, B12, true , 0, 5, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG)
+I(LDXi , "ldx" , 3, 2, B12, true , 0, 5, SPARC_LD, M_INT_FLAG | M_LOAD_FLAG)
// Load floating-point instructions
// Latency includes 1 cycle for address generation (Sparc IIi)
-I(LD , "ld", 3, 2, B12, true , 0, 5, SPARC_LD, M_FLOAT_FLAG | M_LOAD_FLAG)
-I(LDD, "ldd", 3, 2, B12, true , 0, 5, SPARC_LD, M_FLOAT_FLAG | M_LOAD_FLAG)
-I(LDQ, "ldq", 3, 2, B12, true , 0, 5, SPARC_LD, M_FLOAT_FLAG | M_LOAD_FLAG)
-I(LDFSR, "ld", 3, 2, B12, true , 0, 5, SPARC_LD, M_FLOAT_FLAG | M_LOAD_FLAG)
-I(LDXFSR, "ldx", 3, 2, B12, true , 0, 5, SPARC_LD, M_FLOAT_FLAG | M_LOAD_FLAG)
+I(LDFr , "ld", 3, 2, B12, true , 0, 5, SPARC_LD, M_FLOAT_FLAG | M_LOAD_FLAG)
+I(LDFi , "ld", 3, 2, B12, true , 0, 5, SPARC_LD, M_FLOAT_FLAG | M_LOAD_FLAG)
+I(LDDFr, "ldd", 3, 2, B12, true , 0, 5, SPARC_LD, M_FLOAT_FLAG | M_LOAD_FLAG)
+I(LDDFi, "ldd", 3, 2, B12, true , 0, 5, SPARC_LD, M_FLOAT_FLAG | M_LOAD_FLAG)
+I(LDQFr, "ldq", 3, 2, B12, true , 0, 5, SPARC_LD, M_FLOAT_FLAG | M_LOAD_FLAG)
+I(LDQFi, "ldq", 3, 2, B12, true , 0, 5, SPARC_LD, M_FLOAT_FLAG | M_LOAD_FLAG)
+I(LDFSRr, "ld", 3, 2, B12, true , 0, 5, SPARC_LD, M_FLOAT_FLAG | M_LOAD_FLAG)
+I(LDFSRi, "ld", 3, 2, B12, true , 0, 5, SPARC_LD, M_FLOAT_FLAG | M_LOAD_FLAG)
+I(LDXFSRr, "ldx", 3, 2, B12, true , 0, 5, SPARC_LD, M_FLOAT_FLAG | M_LOAD_FLAG)
+I(LDXFSRi, "ldx", 3, 2, B12, true , 0, 5, SPARC_LD, M_FLOAT_FLAG | M_LOAD_FLAG)
// Store integer instructions.
// Requires 1 cycle for address generation (Sparc IIi).
// Default latency is 0 because value is not explicitly used.
-I(STB, "stb", 3, -1, B12, true , 0, 0, SPARC_ST, M_INT_FLAG | M_STORE_FLAG)
-I(STH, "sth", 3, -1, B12, true , 0, 0, SPARC_ST, M_INT_FLAG | M_STORE_FLAG)
-I(STW, "stw", 3, -1, B12, true , 0, 0, SPARC_ST, M_INT_FLAG | M_STORE_FLAG)
-I(STX, "stx", 3, -1, B12, true , 0, 0, SPARC_ST, M_INT_FLAG | M_STORE_FLAG)
+I(STBr, "stb", 3, -1, B12, true , 0, 0, SPARC_ST, M_INT_FLAG | M_STORE_FLAG)
+I(STBi, "stb", 3, -1, B12, true , 0, 0, SPARC_ST, M_INT_FLAG | M_STORE_FLAG)
+I(STHr, "sth", 3, -1, B12, true , 0, 0, SPARC_ST, M_INT_FLAG | M_STORE_FLAG)
+I(STHi, "sth", 3, -1, B12, true , 0, 0, SPARC_ST, M_INT_FLAG | M_STORE_FLAG)
+I(STWr, "stw", 3, -1, B12, true , 0, 0, SPARC_ST, M_INT_FLAG | M_STORE_FLAG)
+I(STWi, "stw", 3, -1, B12, true , 0, 0, SPARC_ST, M_INT_FLAG | M_STORE_FLAG)
+I(STXr, "stx", 3, -1, B12, true , 0, 0, SPARC_ST, M_INT_FLAG | M_STORE_FLAG)
+I(STXi, "stx", 3, -1, B12, true , 0, 0, SPARC_ST, M_INT_FLAG | M_STORE_FLAG)
// Store floating-point instructions (Sparc IIi)
-I(ST , "st", 3, -1, B12, true , 0, 0, SPARC_ST, M_FLOAT_FLAG | M_STORE_FLAG)
-I(STD, "std", 3, -1, B12, true , 0, 0, SPARC_ST, M_FLOAT_FLAG | M_STORE_FLAG)
-I(STFSR, "st", 3, -1, B12, true , 0, 0, SPARC_ST, M_FLOAT_FLAG | M_STORE_FLAG)
-I(STXFSR, "stx", 3, -1, B12, true , 0, 0, SPARC_ST, M_FLOAT_FLAG | M_STORE_FLAG)
+I(STFr, "st", 3, -1, B12, true , 0, 0, SPARC_ST, M_FLOAT_FLAG | M_STORE_FLAG)
+I(STFi, "st", 3, -1, B12, true , 0, 0, SPARC_ST, M_FLOAT_FLAG | M_STORE_FLAG)
+I(STDFr, "std", 3, -1, B12, true , 0, 0, SPARC_ST, M_FLOAT_FLAG | M_STORE_FLAG)
+I(STDFi, "std", 3, -1, B12, true , 0, 0, SPARC_ST, M_FLOAT_FLAG | M_STORE_FLAG)
+I(STFSRr, "st", 3, -1, B12, true , 0, 0, SPARC_ST, M_FLOAT_FLAG | M_STORE_FLAG)
+I(STFSRi, "st", 3, -1, B12, true , 0, 0, SPARC_ST, M_FLOAT_FLAG | M_STORE_FLAG)
+I(STXFSRr, "stx", 3, -1, B12, true , 0, 0, SPARC_ST, M_FLOAT_FLAG | M_STORE_FLAG)
+I(STXFSRi, "stx", 3, -1, B12, true , 0, 0, SPARC_ST, M_FLOAT_FLAG | M_STORE_FLAG)
// Call, Return and "Jump and link". Operand (2) for JMPL is marked as
// a "result" because JMPL stores the return address for the call in it.
// Latency includes the delay slot.
-I(CALL , "call", 1, -1, B29, true , 1, 2, SPARC_CTI, M_CALL_FLAG)
-I(JMPLCALL, "jmpl", 3, 2, B12, true , 1, 2, SPARC_CTI, M_CALL_FLAG)
-I(JMPLRET, "jmpl", 3, 2, B12, true , 1, 2, SPARC_CTI, M_RET_FLAG)
-I(RETURN, "return", 2, -1, 0, false, 1, 2, SPARC_CTI, M_RET_FLAG)
+I(CALL, "call", 1, -1, B29, true , 1, 2, SPARC_CTI, M_CALL_FLAG)
+I(JMPLCALLr, "jmpl", 3, 2, B12, true , 1, 2, SPARC_CTI, M_CALL_FLAG)
+I(JMPLCALLi, "jmpl", 3, 2, B12, true , 1, 2, SPARC_CTI, M_CALL_FLAG)
+I(JMPLRETr, "jmpl", 3, 2, B12, true , 1, 2, SPARC_CTI, M_RET_FLAG)
+I(JMPLRETi, "jmpl", 3, 2, B12, true , 1, 2, SPARC_CTI, M_RET_FLAG)
+I(RETURNr, "return", 2, -1, 0, false, 1, 2, SPARC_CTI, M_RET_FLAG)
+I(RETURNi, "return", 2, -1, 0, false, 1, 2, SPARC_CTI, M_RET_FLAG)
// SAVE and restore instructions
-I(SAVE , "save", 3, 2, B12, true , 0, 1, SPARC_SINGLE, M_INT_FLAG | M_ARITH_FLAG)
-I(RESTORE, "restore", 3, 2, B12, true , 0, 1, SPARC_SINGLE, M_INT_FLAG | M_ARITH_FLAG)
+I(SAVEr, "save", 3, 2, B12, true , 0, 1, SPARC_SINGLE, M_INT_FLAG | M_ARITH_FLAG)
+I(SAVEi, "save", 3, 2, B12, true , 0, 1, SPARC_SINGLE, M_INT_FLAG | M_ARITH_FLAG)
+I(RESTOREr, "restore", 3, 2, B12, true , 0, 1, SPARC_SINGLE, M_INT_FLAG | M_ARITH_FLAG)
+I(RESTOREi, "restore", 3, 2, B12, true , 0, 1, SPARC_SINGLE, M_INT_FLAG | M_ARITH_FLAG)
// Read and Write CCR register from/to an int reg
I(RDCCR, "rd", 2, 2, 0, false, 0, 1, SPARC_SINGLE, M_INT_FLAG | M_CC_FLAG)
From brukman at cs.uiuc.edu Tue May 27 17:34:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 17:34:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/UltraSparcSchedInfo.cpp
Message-ID: <200305272233.RAA31264@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
UltraSparcSchedInfo.cpp updated: 1.4 -> 1.5
---
Log message:
Added entries for each of the instructions with annotations ('r' or 'i').
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/UltraSparcSchedInfo.cpp
diff -u llvm/lib/Target/Sparc/UltraSparcSchedInfo.cpp:1.4 llvm/lib/Target/Sparc/UltraSparcSchedInfo.cpp:1.5
--- llvm/lib/Target/Sparc/UltraSparcSchedInfo.cpp:1.4 Tue May 20 15:32:24 2003
+++ llvm/lib/Target/Sparc/UltraSparcSchedInfo.cpp Tue May 27 17:33:39 2003
@@ -420,10 +420,14 @@
//{ V9::STDA, true, true, 0 },
//{ V9::LDDF, true, true, 0 },
//{ V9::LDDFA, true, true, 0 },
- { V9::ADDC, true, true, 0 },
- { V9::ADDCcc, true, true, 0 },
- { V9::SUBC, true, true, 0 },
- { V9::SUBCcc, true, true, 0 },
+ { V9::ADDCr, true, true, 0 },
+ { V9::ADDCi, true, true, 0 },
+ { V9::ADDCccr, true, true, 0 },
+ { V9::ADDCcci, true, true, 0 },
+ { V9::SUBCr, true, true, 0 },
+ { V9::SUBCi, true, true, 0 },
+ { V9::SUBCccr, true, true, 0 },
+ { V9::SUBCcci, true, true, 0 },
//{ V9::LDSTUB, true, true, 0 },
//{ V9::SWAP, true, true, 0 },
//{ V9::SWAPA, true, true, 0 },
@@ -444,7 +448,8 @@
//{ V9::FLUSH, true, true, 9 },
//{ V9::FLUSHW, true, true, 9 },
//{ V9::ALIGNADDR, true, true, 0 },
- { V9::RETURN, true, true, 0 },
+ { V9::RETURNr, true, true, 0 },
+ { V9::RETURNi, true, true, 0 },
//{ V9::DONE, true, true, 0 },
//{ V9::RETRY, true, true, 0 },
//{ V9::TCC, true, true, 0 },
@@ -453,11 +458,14 @@
// Special cases for breaking group *before*
// CURRENTLY NOT SUPPORTED!
{ V9::CALL, false, false, 0 },
- { V9::JMPLCALL, false, false, 0 },
- { V9::JMPLRET, false, false, 0 },
+ { V9::JMPLCALLr, false, false, 0 },
+ { V9::JMPLCALLi, false, false, 0 },
+ { V9::JMPLRETr, false, false, 0 },
+ { V9::JMPLRETi, false, false, 0 },
// Special cases for breaking the group *after*
- { V9::MULX, true, true, (4+34)/2 },
+ { V9::MULXr, true, true, (4+34)/2 },
+ { V9::MULXi, true, true, (4+34)/2 },
{ V9::FDIVS, false, true, 0 },
{ V9::FDIVD, false, true, 0 },
{ V9::FDIVQ, false, true, 0 },
@@ -470,8 +478,10 @@
//{ V9::MULScc, true, true, 2 },
//{ V9::SMULcc, true, true, (4+18)/2 },
//{ V9::UMULcc, true, true, (4+19)/2 },
- { V9::SDIVX, true, true, 68 },
- { V9::UDIVX, true, true, 68 },
+ { V9::SDIVXr, true, true, 68 },
+ { V9::SDIVXi, true, true, 68 },
+ { V9::UDIVXr, true, true, 68 },
+ { V9::UDIVXi, true, true, 68 },
//{ V9::SDIVcc, true, true, 36 },
//{ V9::UDIVcc, true, true, 37 },
{ V9::WRCCR, true, true, 4 },
@@ -498,8 +508,10 @@
//
// JMPL counts as a load/store instruction for issue!
//
- { V9::JMPLCALL, LSIssueSlots.rid, 0, 1 },
- { V9::JMPLRET, LSIssueSlots.rid, 0, 1 },
+ { V9::JMPLCALLr, LSIssueSlots.rid, 0, 1 },
+ { V9::JMPLCALLi, LSIssueSlots.rid, 0, 1 },
+ { V9::JMPLRETr, LSIssueSlots.rid, 0, 1 },
+ { V9::JMPLRETi, LSIssueSlots.rid, 0, 1 },
//
// Many instructions cannot issue for the next 2 cycles after an FCMP
@@ -509,14 +521,18 @@
{ V9::FCMPD, FCMPDelayCycle.rid, 1, 3 },
{ V9::FCMPQ, FCMPDelayCycle.rid, 1, 3 },
- { V9::MULX, FCMPDelayCycle.rid, 1, 1 },
- { V9::SDIVX, FCMPDelayCycle.rid, 1, 1 },
- { V9::UDIVX, FCMPDelayCycle.rid, 1, 1 },
+ { V9::MULXr, FCMPDelayCycle.rid, 1, 1 },
+ { V9::MULXi, FCMPDelayCycle.rid, 1, 1 },
+ { V9::SDIVXr, FCMPDelayCycle.rid, 1, 1 },
+ { V9::SDIVXi, FCMPDelayCycle.rid, 1, 1 },
+ { V9::UDIVXr, FCMPDelayCycle.rid, 1, 1 },
+ { V9::UDIVXi, FCMPDelayCycle.rid, 1, 1 },
//{ V9::SMULcc, FCMPDelayCycle.rid, 1, 1 },
//{ V9::UMULcc, FCMPDelayCycle.rid, 1, 1 },
//{ V9::SDIVcc, FCMPDelayCycle.rid, 1, 1 },
//{ V9::UDIVcc, FCMPDelayCycle.rid, 1, 1 },
- { V9::STD, FCMPDelayCycle.rid, 1, 1 },
+ { V9::STDFr, FCMPDelayCycle.rid, 1, 1 },
+ { V9::STDFi, FCMPDelayCycle.rid, 1, 1 },
{ V9::FMOVRSZ, FCMPDelayCycle.rid, 1, 1 },
{ V9::FMOVRSLEZ,FCMPDelayCycle.rid, 1, 1 },
{ V9::FMOVRSLZ, FCMPDelayCycle.rid, 1, 1 },
@@ -528,7 +544,8 @@
// Some instructions are stalled in the GROUP stage if a CTI is in
// the E or C stage. We model that with a fake resource CTIDelayCycle.
//
- { V9::LDD, CTIDelayCycle.rid, 1, 1 },
+ { V9::LDDFr, CTIDelayCycle.rid, 1, 1 },
+ { V9::LDDFi, CTIDelayCycle.rid, 1, 1 },
//{ V9::LDDA, CTIDelayCycle.rid, 1, 1 },
//{ V9::LDDSTUB, CTIDelayCycle.rid, 1, 1 },
//{ V9::LDDSTUBA, CTIDelayCycle.rid, 1, 1 },
@@ -543,14 +560,20 @@
// Signed int loads of less than dword size return data in cycle N1 (not C)
// and put all loads in consecutive cycles into delayed load return mode.
//
- { V9::LDSB, LdReturn.rid, 2, -1 },
- { V9::LDSB, LdReturn.rid, 3, 1 },
-
- { V9::LDSH, LdReturn.rid, 2, -1 },
- { V9::LDSH, LdReturn.rid, 3, 1 },
-
- { V9::LDSW, LdReturn.rid, 2, -1 },
- { V9::LDSW, LdReturn.rid, 3, 1 },
+ { V9::LDSBr, LdReturn.rid, 2, -1 },
+ { V9::LDSBr, LdReturn.rid, 3, 1 },
+ { V9::LDSBi, LdReturn.rid, 2, -1 },
+ { V9::LDSBi, LdReturn.rid, 3, 1 },
+
+ { V9::LDSHr, LdReturn.rid, 2, -1 },
+ { V9::LDSHr, LdReturn.rid, 3, 1 },
+ { V9::LDSHi, LdReturn.rid, 2, -1 },
+ { V9::LDSHi, LdReturn.rid, 3, 1 },
+
+ { V9::LDSWr, LdReturn.rid, 2, -1 },
+ { V9::LDSWr, LdReturn.rid, 3, 1 },
+ { V9::LDSWi, LdReturn.rid, 2, -1 },
+ { V9::LDSWi, LdReturn.rid, 3, 1 },
//
// RDPR from certain registers and RD from any register are not dispatchable
@@ -574,7 +597,7 @@
//{ V9::MULScc, AllIssueSlots.rid, 2, 2-1 },
//{ V9::MULScc, AllIssueSlots.rid, 2, 2-1 },
//{ V9::MULScc, AllIssueSlots.rid, 2, 2-1 },
-//{ V9::MULScc, AllIssueSlots.rid, 2, 2-1 },
+//{ V9::MULScc, AllIssueSlots.rid, 2, 2-1 },
//
// SMULcc inserts between 4 and 18 bubbles, depending on #leading 0s in rs1.
@@ -583,13 +606,13 @@
//{ V9::SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
//{ V9::SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
//{ V9::SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
-//{ V9::SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
+//{ V9::SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
// SMULcc inserts between 4 and 19 bubbles, depending on #leading 0s in rs1.
//{ V9::UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
//{ V9::UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
//{ V9::UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
-//{ V9::UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
+//{ V9::UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
//
// MULX inserts between 4 and 34 bubbles, depending on #leading 0s in rs1.
@@ -597,7 +620,7 @@
{ V9::MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
{ V9::MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
{ V9::MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
- { V9::MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
+ { V9::MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
//
// SDIVcc inserts 36 bubbles.
@@ -605,13 +628,13 @@
//{ V9::SDIVcc, AllIssueSlots.rid, 2, 36-1 },
//{ V9::SDIVcc, AllIssueSlots.rid, 2, 36-1 },
//{ V9::SDIVcc, AllIssueSlots.rid, 2, 36-1 },
-//{ V9::SDIVcc, AllIssueSlots.rid, 2, 36-1 },
+//{ V9::SDIVcc, AllIssueSlots.rid, 2, 36-1 },
// UDIVcc inserts 37 bubbles.
//{ V9::UDIVcc, AllIssueSlots.rid, 2, 37-1 },
//{ V9::UDIVcc, AllIssueSlots.rid, 2, 37-1 },
//{ V9::UDIVcc, AllIssueSlots.rid, 2, 37-1 },
-//{ V9::UDIVcc, AllIssueSlots.rid, 2, 37-1 },
+//{ V9::UDIVcc, AllIssueSlots.rid, 2, 37-1 },
//
// SDIVX inserts 68 bubbles.
@@ -619,7 +642,7 @@
{ V9::SDIVX, AllIssueSlots.rid, 2, 68-1 },
{ V9::SDIVX, AllIssueSlots.rid, 2, 68-1 },
{ V9::SDIVX, AllIssueSlots.rid, 2, 68-1 },
- { V9::SDIVX, AllIssueSlots.rid, 2, 68-1 },
+ { V9::SDIVX, AllIssueSlots.rid, 2, 68-1 },
//
// UDIVX inserts 68 bubbles.
@@ -627,7 +650,7 @@
{ V9::UDIVX, AllIssueSlots.rid, 2, 68-1 },
{ V9::UDIVX, AllIssueSlots.rid, 2, 68-1 },
{ V9::UDIVX, AllIssueSlots.rid, 2, 68-1 },
- { V9::UDIVX, AllIssueSlots.rid, 2, 68-1 },
+ { V9::UDIVX, AllIssueSlots.rid, 2, 68-1 },
//
// WR inserts 4 bubbles.
@@ -635,7 +658,7 @@
//{ V9::WR, AllIssueSlots.rid, 2, 68-1 },
//{ V9::WR, AllIssueSlots.rid, 2, 68-1 },
//{ V9::WR, AllIssueSlots.rid, 2, 68-1 },
-//{ V9::WR, AllIssueSlots.rid, 2, 68-1 },
+//{ V9::WR, AllIssueSlots.rid, 2, 68-1 },
//
// WRPR inserts 4 bubbles.
@@ -643,7 +666,7 @@
//{ V9::WRPR, AllIssueSlots.rid, 2, 68-1 },
//{ V9::WRPR, AllIssueSlots.rid, 2, 68-1 },
//{ V9::WRPR, AllIssueSlots.rid, 2, 68-1 },
-//{ V9::WRPR, AllIssueSlots.rid, 2, 68-1 },
+//{ V9::WRPR, AllIssueSlots.rid, 2, 68-1 },
//
// DONE inserts 9 bubbles.
@@ -659,7 +682,7 @@
//{ V9::RETRY, AllIssueSlots.rid, 2, 9-1 },
//{ V9::RETRY, AllIssueSlots.rid, 2, 9-1 },
//{ V9::RETRY, AllIssueSlots.rid, 2, 9-1 },
-//{ V9::RETRY, AllIssueSlots.rid, 2, 9-1 },
+//{ V9::RETRY, AllIssueSlots.rid, 2, 9-1 },
#endif /*EXPLICIT_BUBBLES_NEEDED */
};
From brukman at cs.uiuc.edu Tue May 27 17:35:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 17:35:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/EmitAssembly.cpp
Message-ID: <200305272234.RAA31277@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
EmitAssembly.cpp updated: 1.76 -> 1.77
---
Log message:
Added 'r' or 'i' annotations to instructions, as SparcInstr.def has changed.
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/EmitAssembly.cpp
diff -u llvm/lib/Target/Sparc/EmitAssembly.cpp:1.76 llvm/lib/Target/Sparc/EmitAssembly.cpp:1.77
--- llvm/lib/Target/Sparc/EmitAssembly.cpp:1.76 Mon May 26 19:02:22 2003
+++ llvm/lib/Target/Sparc/EmitAssembly.cpp Tue May 27 17:34:18 2003
@@ -309,7 +309,8 @@
unsigned getOperandMask(unsigned Opcode) {
switch (Opcode) {
- case V9::SUBcc: return 1 << 3; // Remove CC argument
+ case V9::SUBccr:
+ case V9::SUBcci: return 1 << 3; // Remove CC argument
//case BA: return 1 << 0; // Remove Arg #0, which is always null or xcc
default: return 0; // By default, don't hack operands...
}
@@ -320,8 +321,10 @@
SparcFunctionAsmPrinter::OpIsBranchTargetLabel(const MachineInstr *MI,
unsigned int opNum) {
switch (MI->getOpCode()) {
- case V9::JMPLCALL:
- case V9::JMPLRET:
+ case V9::JMPLCALLr:
+ case V9::JMPLCALLi:
+ case V9::JMPLRETr:
+ case V9::JMPLRETi:
return (opNum == 0);
default:
return false;
From brukman at cs.uiuc.edu Tue May 27 17:36:00 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 17:36:00 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInstrInfo.cpp
Message-ID: <200305272235.RAA31314@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
SparcInstrInfo.cpp updated: 1.43 -> 1.44
---
Log message:
Added 'r' or 'i' annotations to instructions, as SparcInstr.def has changed.
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/SparcInstrInfo.cpp
diff -u llvm/lib/Target/Sparc/SparcInstrInfo.cpp:1.43 llvm/lib/Target/Sparc/SparcInstrInfo.cpp:1.44
--- llvm/lib/Target/Sparc/SparcInstrInfo.cpp:1.43 Sun May 25 16:58:11 2003
+++ llvm/lib/Target/Sparc/SparcInstrInfo.cpp Tue May 27 17:35:43 2003
@@ -108,12 +108,12 @@
if (miSETHI==NULL || C & MAXLO) {
if (miSETHI) {
// unsigned value with high-order bits set using SETHI
- miOR = BuildMI(V9::OR,3).addReg(dest).addZImm(C).addRegDef(dest);
+ miOR = BuildMI(V9::ORi,3).addReg(dest).addZImm(C).addRegDef(dest);
miOR->setOperandLo32(1);
} else {
// unsigned or small signed value that fits in simm13 field of OR
assert(smallNegValue || (C & ~MAXSIMM) == 0);
- miOR = BuildMI(V9::OR, 3).addMReg(target.getRegInfo()
+ miOR = BuildMI(V9::ORi, 3).addMReg(target.getRegInfo()
.getZeroRegNum())
.addSImm(sC).addRegDef(dest);
}
@@ -145,7 +145,7 @@
// Sign-extend to the high 32 bits if needed.
// NOTE: The value C = 0x80000000 is bad: -C == C and so -C is < MAXSIMM
if (C < 0 && (C == -C || -C > (int32_t) MAXSIMM))
- mvec.push_back(BuildMI(V9::SRA, 3).addReg(dest).addZImm(0).addRegDef(dest));
+ mvec.push_back(BuildMI(V9::SRAi6, 3).addReg(dest).addZImm(0).addRegDef(dest));
}
@@ -172,14 +172,14 @@
CreateSETUWConst(target, (C >> 32), tmpReg, mvec);
// Shift tmpReg left by 32 bits
- mvec.push_back(BuildMI(V9::SLLX, 3).addReg(tmpReg).addZImm(32)
+ mvec.push_back(BuildMI(V9::SLLXi6, 3).addReg(tmpReg).addZImm(32)
.addRegDef(tmpReg));
// Code to set the low 32 bits of the value in register `dest'
CreateSETUWConst(target, C, dest, mvec);
// dest = OR(tmpReg, dest)
- mvec.push_back(BuildMI(V9::OR,3).addReg(dest).addReg(tmpReg).addRegDef(dest));
+ mvec.push_back(BuildMI(V9::ORr,3).addReg(dest).addReg(tmpReg).addRegDef(dest));
}
@@ -201,7 +201,7 @@
mvec.push_back(MI);
// Set the low 10 bits in dest
- MI = BuildMI(V9::OR, 3).addReg(dest).addReg(val).addRegDef(dest);
+ MI = BuildMI(V9::ORr, 3).addReg(dest).addReg(val).addRegDef(dest);
MI->setOperandLo32(1);
mvec.push_back(MI);
}
@@ -227,20 +227,20 @@
MI->setOperandHi64(0);
mvec.push_back(MI);
- MI = BuildMI(V9::OR, 3).addReg(tmpReg).addPCDisp(val).addRegDef(tmpReg);
+ MI = BuildMI(V9::ORi, 3).addReg(tmpReg).addPCDisp(val).addRegDef(tmpReg);
MI->setOperandLo64(1);
mvec.push_back(MI);
- mvec.push_back(BuildMI(V9::SLLX, 3).addReg(tmpReg).addZImm(32)
+ mvec.push_back(BuildMI(V9::SLLXi6, 3).addReg(tmpReg).addZImm(32)
.addRegDef(tmpReg));
MI = BuildMI(V9::SETHI, 2).addPCDisp(val).addRegDef(dest);
MI->setOperandHi32(0);
mvec.push_back(MI);
- MI = BuildMI(V9::OR, 3).addReg(dest).addReg(tmpReg).addRegDef(dest);
+ MI = BuildMI(V9::ORr, 3).addReg(dest).addReg(tmpReg).addRegDef(dest);
mvec.push_back(MI);
- MI = BuildMI(V9::OR, 3).addReg(dest).addPCDisp(val).addRegDef(dest);
+ MI = BuildMI(V9::ORi, 3).addReg(dest).addPCDisp(val).addRegDef(dest);
MI->setOperandLo32(1);
mvec.push_back(MI);
}
@@ -311,20 +311,20 @@
if (llvmOpCode >= Instruction::BinaryOpsBegin &&
llvmOpCode < Instruction::BinaryOpsEnd)
- modelOpCode = V9::ADD;
+ modelOpCode = V9::ADDi;
else
switch(llvmOpCode) {
- case Instruction::Ret: modelOpCode = V9::JMPLCALL; break;
+ case Instruction::Ret: modelOpCode = V9::JMPLCALLi; break;
case Instruction::Malloc:
case Instruction::Alloca:
case Instruction::GetElementPtr:
case Instruction::PHINode:
case Instruction::Cast:
- case Instruction::Call: modelOpCode = V9::ADD; break;
+ case Instruction::Call: modelOpCode = V9::ADDi; break;
case Instruction::Shl:
- case Instruction::Shr: modelOpCode = V9::SLLX; break;
+ case Instruction::Shr: modelOpCode = V9::SLLXi6; break;
default: break;
};
@@ -673,12 +673,12 @@
TmpInstruction *tmpI = new TmpInstruction(destVal->getType(),
srcVal, destVal, "make32");
mcfi.addTemp(tmpI);
- mvec.push_back(BuildMI(V9::SLLX, 3).addReg(srcVal)
+ mvec.push_back(BuildMI(V9::SLLXi6, 3).addReg(srcVal)
.addZImm(32-numLowBits).addRegDef(tmpI));
srcVal = tmpI;
}
- mvec.push_back(BuildMI(signExtend? V9::SRA : V9::SRL, 3)
+ mvec.push_back(BuildMI(signExtend? V9::SRAi6 : V9::SRLi6, 3)
.addReg(srcVal).addZImm(32-numLowBits).addRegDef(destVal));
}
From brukman at cs.uiuc.edu Tue May 27 17:36:03 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 17:36:03 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/PrologEpilogCodeInserter.cpp
Message-ID: <200305272235.RAA31294@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
PrologEpilogCodeInserter.cpp updated: 1.25 -> 1.26
---
Log message:
Added 'r' or 'i' annotations to instructions, as SparcInstr.def has changed.
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/PrologEpilogCodeInserter.cpp
diff -u llvm/lib/Target/Sparc/PrologEpilogCodeInserter.cpp:1.25 llvm/lib/Target/Sparc/PrologEpilogCodeInserter.cpp:1.26
--- llvm/lib/Target/Sparc/PrologEpilogCodeInserter.cpp:1.25 Sun May 25 10:59:47 2003
+++ llvm/lib/Target/Sparc/PrologEpilogCodeInserter.cpp Tue May 27 17:35:03 2003
@@ -63,9 +63,9 @@
int32_t C = - (int) staticStackSize;
int SP = TM.getRegInfo().getStackPointer();
- if (TM.getInstrInfo().constantFitsInImmedField(V9::SAVE,staticStackSize)) {
- mvec.push_back(BuildMI(V9::SAVE, 3).addMReg(SP).addSImm(C).addMReg(SP,
- MOTy::Def));
+ if (TM.getInstrInfo().constantFitsInImmedField(V9::SAVEi,staticStackSize)) {
+ mvec.push_back(BuildMI(V9::SAVEi, 3).addMReg(SP).addSImm(C)
+ .addMReg(SP, MOTy::Def));
} else {
// We have to put the stack size value into a register before SAVE.
// Use register %g1 since it is volatile across calls. Note that the
@@ -81,17 +81,17 @@
M->setOperandHi32(0);
mvec.push_back(M);
- M = BuildMI(V9::OR, 3).addMReg(uregNum).addSImm(C)
+ M = BuildMI(V9::ORi, 3).addMReg(uregNum).addSImm(C)
.addMReg(uregNum, MOTy::Def);
M->setOperandLo32(1);
mvec.push_back(M);
- M = BuildMI(V9::SRA, 3).addMReg(uregNum).addZImm(0)
+ M = BuildMI(V9::SRAi6, 3).addMReg(uregNum).addZImm(0)
.addMReg(uregNum, MOTy::Def);
mvec.push_back(M);
// Now generate the SAVE using the value in register %g1
- M = BuildMI(V9::SAVE, 3).addMReg(SP).addMReg(uregNum).addMReg(SP,MOTy::Def);
+ M = BuildMI(V9::SAVEr,3).addMReg(SP).addMReg(uregNum).addMReg(SP,MOTy::Def);
mvec.push_back(M);
}
@@ -116,7 +116,7 @@
int nextArgOffset = firstArgOffset + numFixedArgs * argSize;
for (int i=numFixedArgs; i < numArgRegs; ++i) {
- mvec.push_back(BuildMI(V9::STX, 3).addMReg(firstArgReg+i).
+ mvec.push_back(BuildMI(V9::STXi, 3).addMReg(firstArgReg+i).
addMReg(fpReg).addSImm(nextArgOffset));
nextArgOffset += argSize;
}
@@ -139,7 +139,7 @@
{
int ZR = TM.getRegInfo().getZeroRegNum();
MachineInstr *Restore =
- BuildMI(V9::RESTORE, 3).addMReg(ZR).addSImm(0).addMReg(ZR, MOTy::Def);
+ BuildMI(V9::RESTOREi, 3).addMReg(ZR).addSImm(0).addMReg(ZR, MOTy::Def);
MachineCodeForInstruction &termMvec =
MachineCodeForInstruction::get(TermInst);
From vadve at cs.uiuc.edu Tue May 27 17:37:01 2003
From: vadve at cs.uiuc.edu (Vikram Adve)
Date: Tue May 27 17:37:01 2003
Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/aha/Makefile
Message-ID: <200305272236.RAA13825@psmith.cs.uiuc.edu>
Changes in directory llvm/test/Programs/MultiSource/aha:
Makefile updated: 1.2 -> 1.3
---
Log message:
Increase limit for aha to 300 seconds since the Sparcs are so slow!
---
Diffs of the changes:
Index: llvm/test/Programs/MultiSource/aha/Makefile
diff -u llvm/test/Programs/MultiSource/aha/Makefile:1.2 llvm/test/Programs/MultiSource/aha/Makefile:1.3
--- llvm/test/Programs/MultiSource/aha/Makefile:1.2 Mon May 12 11:03:21 2003
+++ llvm/test/Programs/MultiSource/aha/Makefile Tue May 27 17:36:34 2003
@@ -2,5 +2,5 @@
PROG = aha
CPPFLAGS =
LDFLAGS =
-RUNTIMELIMIT = 60
+RUNTIMELIMIT = 300
include ../Makefile.multisrc
From brukman at cs.uiuc.edu Tue May 27 17:38:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 17:38:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInstrSelection.cpp
Message-ID: <200305272237.RAA31328@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
SparcInstrSelection.cpp updated: 1.94 -> 1.95
---
Log message:
Added 'r' or 'i' annotations to instructions, as SparcInstr.def has changed.
Here I had to make one non-trivial change: add a function to get a version of
the opcode that takes an immediate, given an opcode that takes all registers.
This is required because sometimes it is not known at construction time which
opcode is used because opcodes are passed around between functions.
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/SparcInstrSelection.cpp
diff -u llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.94 llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.95
--- llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.94 Mon May 26 19:02:22 2003
+++ llvm/lib/Target/Sparc/SparcInstrSelection.cpp Tue May 27 17:37:00 2003
@@ -618,7 +618,7 @@
MachineOpCode opCode = V9::INVALID_OPCODE;
if (resultType->isInteger() || isa(resultType)) {
- opCode = V9::SUB;
+ opCode = V9::SUBr;
} else {
switch(resultType->getPrimitiveID())
{
@@ -695,7 +695,7 @@
MachineOpCode opCode = V9::INVALID_OPCODE;
if (resultType->isInteger())
- opCode = V9::MULX;
+ opCode = V9::MULXr;
else
switch(resultType->getPrimitiveID())
{
@@ -713,7 +713,7 @@
CreateIntNegInstruction(const TargetMachine& target,
Value* vreg)
{
- return BuildMI(V9::SUB, 3).addMReg(target.getRegInfo().getZeroRegNum())
+ return BuildMI(V9::SUBr, 3).addMReg(target.getRegInfo().getZeroRegNum())
.addReg(vreg).addRegDef(vreg);
}
@@ -747,7 +747,7 @@
//
Value* shiftDest = destVal;
unsigned opSize = target.getTargetData().getTypeSize(argVal1->getType());
- if ((shiftOpCode == V9::SLL || shiftOpCode == V9::SLLX) && opSize < 8)
+ if ((shiftOpCode == V9::SLLr6 || shiftOpCode == V9::SLLXr6) && opSize < 8)
{ // put SLL result into a temporary
shiftDest = new TmpInstruction(argVal1, optArgVal2, "sllTmp");
mcfi.addTemp(shiftDest);
@@ -781,7 +781,7 @@
MachineCodeForInstruction& mcfi)
{
/* Use max. multiply cost, viz., cost of MULX */
- unsigned cost = target.getInstrInfo().minLatency(V9::MULX);
+ unsigned cost = target.getInstrInfo().minLatency(V9::MULXr);
unsigned firstNewInstr = mvec.size();
Value* constOp = rval;
@@ -806,18 +806,18 @@
}
if (C == 0 || C == 1) {
- cost = target.getInstrInfo().minLatency(V9::ADD);
+ cost = target.getInstrInfo().minLatency(V9::ADDr);
unsigned Zero = target.getRegInfo().getZeroRegNum();
MachineInstr* M;
if (C == 0)
- M = BuildMI(V9::ADD,3).addMReg(Zero).addMReg(Zero).addRegDef(destVal);
+ M =BuildMI(V9::ADDr,3).addMReg(Zero).addMReg(Zero).addRegDef(destVal);
else
- M = BuildMI(V9::ADD,3).addReg(lval).addMReg(Zero).addRegDef(destVal);
+ M = BuildMI(V9::ADDr,3).addReg(lval).addMReg(Zero).addRegDef(destVal);
mvec.push_back(M);
}
else if (isPowerOf2(C, pow)) {
unsigned opSize = target.getTargetData().getTypeSize(resultType);
- MachineOpCode opCode = (opSize <= 32)? V9::SLL : V9::SLLX;
+ MachineOpCode opCode = (opSize <= 32)? V9::SLLr6 : V9::SLLXr6;
CreateShiftInstructions(target, F, opCode, lval, NULL, pow,
destVal, mvec, mcfi);
}
@@ -913,7 +913,7 @@
const Type* resultType = instrNode->getInstruction()->getType();
if (resultType->isInteger())
- opCode = resultType->isSigned()? V9::SDIVX : V9::UDIVX;
+ opCode = resultType->isSigned()? V9::SDIVXr : V9::UDIVXr;
else
switch(resultType->getPrimitiveID())
{
@@ -959,7 +959,7 @@
}
if (C == 1) {
- mvec.push_back(BuildMI(V9::ADD, 3).addReg(LHS).addMReg(ZeroReg)
+ mvec.push_back(BuildMI(V9::ADDr, 3).addReg(LHS).addMReg(ZeroReg)
.addRegDef(destVal));
} else if (isPowerOf2(C, pow)) {
unsigned opCode;
@@ -982,23 +982,24 @@
mcfi.addTemp(addTmp);
// Create the SRL or SRLX instruction to get the sign bit
- mvec.push_back(BuildMI((resultType==Type::LongTy)? V9::SRLX:V9::SRL,3)
+ mvec.push_back(BuildMI((resultType==Type::LongTy) ?
+ V9::SRLXi6 : V9::SRLi6, 3)
.addReg(LHS)
.addSImm((resultType==Type::LongTy)? 63 : 31)
.addRegDef(srlTmp));
// Create the ADD instruction to add 1 for negative values
- mvec.push_back(BuildMI(V9::ADD, 3).addReg(LHS).addReg(srlTmp)
+ mvec.push_back(BuildMI(V9::ADDr, 3).addReg(LHS).addReg(srlTmp)
.addRegDef(addTmp));
// Get the shift operand and "right-shift" opcode to do the divide
shiftOperand = addTmp;
- opCode = (resultType==Type::LongTy) ? V9::SRAX : V9::SRA;
+ opCode = (resultType==Type::LongTy) ? V9::SRAXi6 : V9::SRAi6;
}
else {
// Get the shift operand and "right-shift" opcode to do the divide
shiftOperand = LHS;
- opCode = (resultType==Type::LongTy) ? V9::SRLX : V9::SRL;
+ opCode = (resultType==Type::LongTy) ? V9::SRLXi6 : V9::SRLi6;
}
// Now do the actual shift!
@@ -1088,11 +1089,11 @@
unsigned SPReg = target.getRegInfo().getStackPointer();
// Instruction 2: sub %sp, totalSizeVal -> %sp
- getMvec.push_back(BuildMI(V9::SUB, 3).addMReg(SPReg).addReg(totalSizeVal)
+ getMvec.push_back(BuildMI(V9::SUBr, 3).addMReg(SPReg).addReg(totalSizeVal)
.addMReg(SPReg,MOTy::Def));
// Instruction 3: add %sp, frameSizeBelowDynamicArea -> result
- getMvec.push_back(BuildMI(V9::ADD, 3).addMReg(SPReg).addReg(dynamicAreaOffset)
+ getMvec.push_back(BuildMI(V9::ADDr,3).addMReg(SPReg).addReg(dynamicAreaOffset)
.addRegDef(result));
}
@@ -1118,7 +1119,7 @@
int offsetFromFP = mcInfo.getInfo()->computeOffsetforLocalVar(result,
paddedSizeIgnored,
tsize * numElements);
- if (! target.getInstrInfo().constantFitsInImmedField(V9::LDX, offsetFromFP)) {
+ if (! target.getInstrInfo().constantFitsInImmedField(V9::LDXi,offsetFromFP)) {
CreateCodeForVariableSizeAlloca(target, result, tsize,
ConstantSInt::get(Type::IntTy,numElements),
getMvec);
@@ -1134,11 +1135,44 @@
// Instruction 1: add %fp, offsetFromFP -> result
unsigned FPReg = target.getRegInfo().getFramePointer();
- getMvec.push_back(BuildMI(V9::ADD, 3).addMReg(FPReg).addReg(offsetVal)
+ getMvec.push_back(BuildMI(V9::ADDr, 3).addMReg(FPReg).addReg(offsetVal)
.addRegDef(result));
}
+static unsigned
+convertOpcodeFromRegToImm(unsigned Opcode) {
+ switch (Opcode) {
+ case V9::ADDr: return V9::ADDi;
+
+ /* load opcodes */
+ case V9::LDUBr: return V9::LDUBi;
+ case V9::LDSBr: return V9::LDSBi;
+ case V9::LDUHr: return V9::LDUHi;
+ case V9::LDSHr: return V9::LDSHi;
+ case V9::LDUWr: return V9::LDUWi;
+ case V9::LDSWr: return V9::LDSWi;
+ case V9::LDXr: return V9::LDXi;
+ case V9::LDFr: return V9::LDFi;
+ case V9::LDDFr: return V9::LDDFi;
+
+ /* store opcodes */
+ case V9::STBr: return V9::STBi;
+ case V9::STHr: return V9::STHi;
+ case V9::STWr: return V9::STWi;
+ case V9::STXr: return V9::STXi;
+ case V9::STFr: return V9::STFi;
+ case V9::STDFr: return V9::STDFi;
+
+ default:
+ std::cerr << "Not handled opcode in convert from reg to imm: " << Opcode
+ << "\n";
+ abort();
+ return 0;
+ }
+}
+
+
//------------------------------------------------------------------------
// Function SetOperandsForMemInstr
//
@@ -1248,16 +1282,20 @@
if (offsetOpType == MachineOperand::MO_VirtualRegister)
MI = BuildMI(Opcode, 3).addReg(vmInstrNode->leftChild()->getValue())
.addReg(ptrVal).addReg(valueForRegOffset);
- else
+ else {
+ Opcode = convertOpcodeFromRegToImm(Opcode);
MI = BuildMI(Opcode, 3).addReg(vmInstrNode->leftChild()->getValue())
.addReg(ptrVal).addSImm(smallConstOffset);
+ }
} else {
if (offsetOpType == MachineOperand::MO_VirtualRegister)
MI = BuildMI(Opcode, 3).addReg(ptrVal).addReg(valueForRegOffset)
.addRegDef(memInst);
- else
+ else {
+ Opcode = convertOpcodeFromRegToImm(Opcode);
MI = BuildMI(Opcode, 3).addReg(ptrVal).addSImm(smallConstOffset)
.addRegDef(memInst);
+ }
}
mvec.push_back(MI);
}
@@ -1355,7 +1393,7 @@
int argSize = target.getFrameInfo().getSizeOfEachArgOnStack();
int firstVarArgOff = numFixedArgs * argSize + target.getFrameInfo().
getFirstIncomingArgOffset(MachineFunction::get(func), ignore);
- mvec.push_back(BuildMI(V9::ADD, 3).addMReg(fpReg).addSImm(firstVarArgOff).
+ mvec.push_back(BuildMI(V9::ADDi, 3).addMReg(fpReg).addSImm(firstVarArgOff).
addReg(callInstr.getOperand(1)));
return true;
}
@@ -1365,7 +1403,7 @@
case LLVMIntrinsic::va_copy:
// Simple copy of current va_list (arg2) to new va_list (arg1)
- mvec.push_back(BuildMI(V9::OR, 3).
+ mvec.push_back(BuildMI(V9::ORr, 3).
addMReg(target.getRegInfo().getZeroRegNum()).
addReg(callInstr.getOperand(2)).
addReg(callInstr.getOperand(1)));
@@ -1482,7 +1520,7 @@
Instruction* returnReg = new TmpInstruction(returnInstr);
MachineCodeForInstruction::get(returnInstr).addTemp(returnReg);
- M = BuildMI(V9::JMPLRET, 3).addReg(returnReg).addSImm(8)
+ M = BuildMI(V9::JMPLRETi, 3).addReg(returnReg).addSImm(8)
.addMReg(target.getRegInfo().getZeroRegNum(), MOTy::Def);
if (returnInstr->getReturnValue() != NULL)
@@ -1634,7 +1672,7 @@
Value* notArg = BinaryOperator::getNotArgument(
cast(subtreeRoot->getInstruction()));
unsigned ZeroReg = target.getRegInfo().getZeroRegNum();
- mvec.push_back(BuildMI(V9::XNOR, 3).addReg(notArg).addMReg(ZeroReg)
+ mvec.push_back(BuildMI(V9::XNORr, 3).addReg(notArg).addMReg(ZeroReg)
.addRegDef(subtreeRoot->getValue()));
break;
}
@@ -1935,7 +1973,7 @@
case 238: // bool: And(bool, boolconst)
case 338: // reg : BAnd(reg, reg)
case 538: // reg : BAnd(reg, Constant)
- Add3OperandInstr(V9::AND, subtreeRoot, mvec);
+ Add3OperandInstr(V9::ANDr, subtreeRoot, mvec);
break;
case 138: // bool: And(bool, not)
@@ -1948,7 +1986,7 @@
notNode->markFoldedIntoParent();
Value *LHS = subtreeRoot->leftChild()->getValue();
Value *Dest = subtreeRoot->getValue();
- mvec.push_back(BuildMI(V9::ANDN, 3).addReg(LHS).addReg(notArg)
+ mvec.push_back(BuildMI(V9::ANDNr, 3).addReg(LHS).addReg(notArg)
.addReg(Dest, MOTy::Def));
break;
}
@@ -1957,7 +1995,7 @@
case 239: // bool: Or(bool, boolconst)
case 339: // reg : BOr(reg, reg)
case 539: // reg : BOr(reg, Constant)
- Add3OperandInstr(V9::OR, subtreeRoot, mvec);
+ Add3OperandInstr(V9::ORr, subtreeRoot, mvec);
break;
case 139: // bool: Or(bool, not)
@@ -1970,7 +2008,7 @@
notNode->markFoldedIntoParent();
Value *LHS = subtreeRoot->leftChild()->getValue();
Value *Dest = subtreeRoot->getValue();
- mvec.push_back(BuildMI(V9::ORN, 3).addReg(LHS).addReg(notArg)
+ mvec.push_back(BuildMI(V9::ORNr, 3).addReg(LHS).addReg(notArg)
.addReg(Dest, MOTy::Def));
break;
}
@@ -1979,7 +2017,7 @@
case 240: // bool: Xor(bool, boolconst)
case 340: // reg : BXor(reg, reg)
case 540: // reg : BXor(reg, Constant)
- Add3OperandInstr(V9::XOR, subtreeRoot, mvec);
+ Add3OperandInstr(V9::XORr, subtreeRoot, mvec);
break;
case 140: // bool: Xor(bool, not)
@@ -1992,7 +2030,7 @@
notNode->markFoldedIntoParent();
Value *LHS = subtreeRoot->leftChild()->getValue();
Value *Dest = subtreeRoot->getValue();
- mvec.push_back(BuildMI(V9::XNOR, 3).addReg(LHS).addReg(notArg)
+ mvec.push_back(BuildMI(V9::XNORr, 3).addReg(LHS).addReg(notArg)
.addReg(Dest, MOTy::Def));
break;
}
@@ -2059,13 +2097,13 @@
// result of SUBcc instruction anyway.
//
if (keepSubVal) {
- M = BuildMI(V9::SUBcc, 4)
+ M = BuildMI(V9::SUBccr, 4)
.addReg(subtreeRoot->leftChild()->getValue())
.addReg(subtreeRoot->rightChild()->getValue())
.addRegDef(subtreeRoot->getValue())
.addCCReg(tmpForCC, MOTy::Def);
} else {
- M = BuildMI(V9::SUBcc, 4)
+ M = BuildMI(V9::SUBccr, 4)
.addReg(subtreeRoot->leftChild()->getValue())
.addReg(subtreeRoot->rightChild()->getValue())
.addMReg(target.getRegInfo().getZeroRegNum(), MOTy::Def)
@@ -2125,7 +2163,7 @@
case 56: // reg: GetElemPtrIdx(reg,reg)
// If the GetElemPtr was folded into the user (parent), it will be
// caught above. For other cases, we have to compute the address.
- SetOperandsForMemInstr(V9::ADD, mvec, subtreeRoot, target);
+ SetOperandsForMemInstr(V9::ADDr, mvec, subtreeRoot, target);
break;
case 57: // reg: Alloca: Implement as 1 instruction:
@@ -2207,7 +2245,7 @@
if (calledFunc) // direct function call
M = BuildMI(V9::CALL, 1).addPCDisp(callee);
else // indirect function call
- M = BuildMI(V9::JMPLCALL, 3).addReg(callee).addSImm((int64_t)0)
+ M = BuildMI(V9::JMPLCALLi, 3).addReg(callee).addSImm((int64_t)0)
.addRegDef(retAddrReg);
mvec.push_back(M);
@@ -2299,7 +2337,7 @@
"Shl unsupported for other types");
CreateShiftInstructions(target, shlInstr->getParent()->getParent(),
- (opType == Type::LongTy)? V9::SLLX : V9::SLL,
+ (opType == Type::LongTy)? V9::SLLXr6:V9::SLLr6,
argVal1, argVal2, 0, shlInstr, mvec,
MachineCodeForInstruction::get(shlInstr));
break;
@@ -2310,8 +2348,8 @@
assert((opType->isInteger() || isa(opType)) &&
"Shr unsupported for other types");
Add3OperandInstr(opType->isSigned()
- ? (opType == Type::LongTy ? V9::SRAX : V9::SRA)
- : (opType == Type::LongTy ? V9::SRLX : V9::SRL),
+ ? (opType == Type::LongTy ? V9::SRAXr6 : V9::SRAr6)
+ : (opType == Type::LongTy ? V9::SRLXr6 : V9::SRLr6),
subtreeRoot, mvec);
break;
}
@@ -2325,9 +2363,9 @@
// Load argument via current pointer value, then increment pointer.
int argSize = target.getFrameInfo().getSizeOfEachArgOnStack();
Instruction* vaArgI = subtreeRoot->getInstruction();
- mvec.push_back(BuildMI(V9::LDX, 3).addReg(vaArgI->getOperand(0)).
+ mvec.push_back(BuildMI(V9::LDXi, 3).addReg(vaArgI->getOperand(0)).
addSImm(0).addRegDef(vaArgI));
- mvec.push_back(BuildMI(V9::ADD, 3).addReg(vaArgI->getOperand(0)).
+ mvec.push_back(BuildMI(V9::ADDi, 3).addReg(vaArgI->getOperand(0)).
addSImm(argSize).addRegDef(vaArgI->getOperand(0)));
break;
}
@@ -2384,7 +2422,7 @@
for (unsigned i=0, N=mvec.size(); i < N; ++i)
mvec[i]->substituteValue(dest, tmpI);
- M = BuildMI(V9::SRL, 3).addReg(tmpI).addZImm(8*(4-destSize))
+ M = BuildMI(V9::SRLi6, 3).addReg(tmpI).addZImm(8*(4-destSize))
.addReg(dest, MOTy::Def);
mvec.push_back(M);
}
From brukman at cs.uiuc.edu Tue May 27 17:40:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 17:40:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcOptInfo.cpp
Message-ID: <200305272239.RAA31360@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
SparcOptInfo.cpp updated: 1.7 -> 1.8
---
Log message:
Added 'r' and 'i' annotations to instructions as SparcInstr.def has changed.
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/SparcOptInfo.cpp
diff -u llvm/lib/Target/Sparc/SparcOptInfo.cpp:1.7 llvm/lib/Target/Sparc/SparcOptInfo.cpp:1.8
--- llvm/lib/Target/Sparc/SparcOptInfo.cpp:1.7 Mon May 26 19:02:22 2003
+++ llvm/lib/Target/Sparc/SparcOptInfo.cpp Tue May 27 17:39:29 2003
@@ -25,7 +25,7 @@
return (/* both operands are allocated to the same register */
MI->getOperand(0).getAllocatedRegNum() ==
MI->getOperand(1).getAllocatedRegNum());
- } else if (MI->getOpCode() == V9::ADD || MI->getOpCode() == V9::OR){
+ } else if (MI->getOpCode() == V9::ADDr || MI->getOpCode() == V9::ORr) {
unsigned srcWithDestReg;
for (srcWithDestReg = 0; srcWithDestReg < 2; ++srcWithDestReg)
From brukman at cs.uiuc.edu Tue May 27 17:40:04 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 17:40:04 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInstrSelectionSupport.h
Message-ID: <200305272239.RAA31342@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
SparcInstrSelectionSupport.h updated: 1.6 -> 1.7
---
Log message:
Added 'r' or 'i' annotations to instructions, as SparcInstr.def has changed.
Non-obvious change: since I have changed ST and STD to be STF and STDF to
(a) closer resemble their name (NOT assembly text) in the Sparc manual, and
(b) clearly specify that they they are floating-point opcodes,
I made the same changes in this file.
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/SparcInstrSelectionSupport.h
diff -u llvm/lib/Target/Sparc/SparcInstrSelectionSupport.h:1.6 llvm/lib/Target/Sparc/SparcInstrSelectionSupport.h:1.7
--- llvm/lib/Target/Sparc/SparcInstrSelectionSupport.h:1.6 Tue May 20 15:32:24 2003
+++ llvm/lib/Target/Sparc/SparcInstrSelectionSupport.h Tue May 27 17:39:01 2003
@@ -14,17 +14,17 @@
{
switch (DestTy->getPrimitiveID()) {
case Type::BoolTyID:
- case Type::UByteTyID: return V9::LDUB;
- case Type::SByteTyID: return V9::LDSB;
- case Type::UShortTyID: return V9::LDUH;
- case Type::ShortTyID: return V9::LDSH;
- case Type::UIntTyID: return V9::LDUW;
- case Type::IntTyID: return V9::LDSW;
+ case Type::UByteTyID: return V9::LDUBr;
+ case Type::SByteTyID: return V9::LDSBr;
+ case Type::UShortTyID: return V9::LDUHr;
+ case Type::ShortTyID: return V9::LDSHr;
+ case Type::UIntTyID: return V9::LDUWr;
+ case Type::IntTyID: return V9::LDSWr;
case Type::PointerTyID:
case Type::ULongTyID:
- case Type::LongTyID: return V9::LDX;
- case Type::FloatTyID: return V9::LD;
- case Type::DoubleTyID: return V9::LDD;
+ case Type::LongTyID: return V9::LDXr;
+ case Type::FloatTyID: return V9::LDFr;
+ case Type::DoubleTyID: return V9::LDDFr;
default: assert(0 && "Invalid type for Load instruction");
}
@@ -37,16 +37,16 @@
switch (DestTy->getPrimitiveID()) {
case Type::BoolTyID:
case Type::UByteTyID:
- case Type::SByteTyID: return V9::STB;
+ case Type::SByteTyID: return V9::STBr;
case Type::UShortTyID:
- case Type::ShortTyID: return V9::STH;
+ case Type::ShortTyID: return V9::STHr;
case Type::UIntTyID:
- case Type::IntTyID: return V9::STW;
+ case Type::IntTyID: return V9::STWr;
case Type::PointerTyID:
case Type::ULongTyID:
- case Type::LongTyID: return V9::STX;
- case Type::FloatTyID: return V9::ST;
- case Type::DoubleTyID: return V9::STD;
+ case Type::LongTyID: return V9::STXr;
+ case Type::FloatTyID: return V9::STFr;
+ case Type::DoubleTyID: return V9::STDFr;
default: assert(0 && "Invalid type for Store instruction");
}
@@ -64,7 +64,7 @@
isa(resultType) ||
resultType == Type::LabelTy)
{
- opCode = V9::ADD;
+ opCode = V9::ADDr;
}
else
switch(resultType->getPrimitiveID())
From brukman at cs.uiuc.edu Tue May 27 17:41:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 17:41:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcRegInfo.cpp
Message-ID: <200305272240.RAA31375@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
SparcRegInfo.cpp updated: 1.94 -> 1.95
---
Log message:
Added 'r' and 'i' annotations to instructions as SparcInstr.def has changed.
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/SparcRegInfo.cpp
diff -u llvm/lib/Target/Sparc/SparcRegInfo.cpp:1.94 llvm/lib/Target/Sparc/SparcRegInfo.cpp:1.95
--- llvm/lib/Target/Sparc/SparcRegInfo.cpp:1.94 Mon May 26 19:02:22 2003
+++ llvm/lib/Target/Sparc/SparcRegInfo.cpp Tue May 27 17:40:34 2003
@@ -1096,7 +1096,7 @@
break;
case IntRegType:
- MI = BuildMI(V9::ADD, 3).addMReg(SrcReg).addMReg(getZeroRegNum())
+ MI = BuildMI(V9::ADDr, 3).addMReg(SrcReg).addMReg(getZeroRegNum())
.addMReg(DestReg, MOTy::Def);
break;
@@ -1132,18 +1132,21 @@
MachineInstr * MI = NULL;
switch (RegType) {
case IntRegType:
- assert(target.getInstrInfo().constantFitsInImmedField(V9::STX, Offset));
- MI = BuildMI(V9::STX,3).addMReg(SrcReg).addMReg(DestPtrReg).addSImm(Offset);
+ assert(target.getInstrInfo().constantFitsInImmedField(V9::STXi, Offset));
+ MI = BuildMI(V9::STXi,3).addMReg(SrcReg).addMReg(DestPtrReg)
+ .addSImm(Offset);
break;
case FPSingleRegType:
- assert(target.getInstrInfo().constantFitsInImmedField(V9::ST, Offset));
- MI = BuildMI(V9::ST, 3).addMReg(SrcReg).addMReg(DestPtrReg).addSImm(Offset);
+ assert(target.getInstrInfo().constantFitsInImmedField(V9::STFi, Offset));
+ MI = BuildMI(V9::STFi, 3).addMReg(SrcReg).addMReg(DestPtrReg)
+ .addSImm(Offset);
break;
case FPDoubleRegType:
- assert(target.getInstrInfo().constantFitsInImmedField(V9::STD, Offset));
- MI = BuildMI(V9::STD,3).addMReg(SrcReg).addMReg(DestPtrReg).addSImm(Offset);
+ assert(target.getInstrInfo().constantFitsInImmedField(V9::STDFi, Offset));
+ MI = BuildMI(V9::STDFi,3).addMReg(SrcReg).addMReg(DestPtrReg)
+ .addSImm(Offset);
break;
case IntCCRegType:
@@ -1158,10 +1161,10 @@
return;
case FloatCCRegType: {
- assert(target.getInstrInfo().constantFitsInImmedField(V9::STXFSR, Offset));
+ assert(target.getInstrInfo().constantFitsInImmedField(V9::STXFSRi, Offset));
unsigned fsrRegNum = getUnifiedRegNum(UltraSparcRegInfo::SpecialRegClassID,
SparcSpecialRegClass::fsr);
- MI = BuildMI(V9::STXFSR, 3)
+ MI = BuildMI(V9::STXFSRi, 3)
.addMReg(fsrRegNum).addMReg(DestPtrReg).addSImm(Offset);
break;
}
@@ -1188,21 +1191,21 @@
MachineInstr * MI = NULL;
switch (RegType) {
case IntRegType:
- assert(target.getInstrInfo().constantFitsInImmedField(V9::LDX, Offset));
- MI = BuildMI(V9::LDX, 3).addMReg(SrcPtrReg).addSImm(Offset)
+ assert(target.getInstrInfo().constantFitsInImmedField(V9::LDXi, Offset));
+ MI = BuildMI(V9::LDXi, 3).addMReg(SrcPtrReg).addSImm(Offset)
.addMReg(DestReg, MOTy::Def);
break;
case FPSingleRegType:
- assert(target.getInstrInfo().constantFitsInImmedField(V9::LD, Offset));
- MI = BuildMI(V9::LD, 3).addMReg(SrcPtrReg).addSImm(Offset)
+ assert(target.getInstrInfo().constantFitsInImmedField(V9::LDFi, Offset));
+ MI = BuildMI(V9::LDFi, 3).addMReg(SrcPtrReg).addSImm(Offset)
.addMReg(DestReg, MOTy::Def);
break;
case FPDoubleRegType:
- assert(target.getInstrInfo().constantFitsInImmedField(V9::LDD, Offset));
- MI = BuildMI(V9::LDD, 3).addMReg(SrcPtrReg).addSImm(Offset).addMReg(DestReg,
- MOTy::Def);
+ assert(target.getInstrInfo().constantFitsInImmedField(V9::LDDFi, Offset));
+ MI = BuildMI(V9::LDDFi, 3).addMReg(SrcPtrReg).addSImm(Offset)
+ .addMReg(DestReg, MOTy::Def);
break;
case IntCCRegType:
@@ -1215,10 +1218,10 @@
break;
case FloatCCRegType: {
- assert(target.getInstrInfo().constantFitsInImmedField(V9::LDXFSR, Offset));
+ assert(target.getInstrInfo().constantFitsInImmedField(V9::LDXFSRi, Offset));
unsigned fsrRegNum = getUnifiedRegNum(UltraSparcRegInfo::SpecialRegClassID,
SparcSpecialRegClass::fsr);
- MI = BuildMI(V9::LDXFSR, 3).addMReg(SrcPtrReg).addSImm(Offset)
+ MI = BuildMI(V9::LDXFSRi, 3).addMReg(SrcPtrReg).addSImm(Offset)
.addMReg(fsrRegNum, MOTy::UseAndDef);
break;
}
@@ -1243,7 +1246,7 @@
switch( RegType ) {
case IntRegType:
- MI = BuildMI(V9::ADD, 3).addReg(Src).addMReg(getZeroRegNum())
+ MI = BuildMI(V9::ADDr, 3).addReg(Src).addMReg(getZeroRegNum())
.addRegDef(Dest);
break;
case FPSingleRegType:
From brukman at cs.uiuc.edu Tue May 27 17:42:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 17:42:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcV9CodeEmitter.h SparcV9CodeEmitter.cpp
Message-ID: <200305272241.RAA31396@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
SparcV9CodeEmitter.h updated: 1.1 -> 1.2
SparcV9CodeEmitter.cpp updated: 1.2 -> 1.3
---
Log message:
Keep track of the current BasicBlock being processed so that a referencing
MachineInstr can later be patched up correctly.
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/SparcV9CodeEmitter.h
diff -u llvm/lib/Target/Sparc/SparcV9CodeEmitter.h:1.1 llvm/lib/Target/Sparc/SparcV9CodeEmitter.h:1.2
--- llvm/lib/Target/Sparc/SparcV9CodeEmitter.h:1.1 Tue May 27 16:45:05 2003
+++ llvm/lib/Target/Sparc/SparcV9CodeEmitter.h Tue May 27 17:41:44 2003
@@ -3,12 +3,14 @@
#ifndef SPARCV9CODEEMITTER_H
#define SPARCV9CODEEMITTER_H
+#include "llvm/BasicBlock.h"
#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
class SparcV9CodeEmitter : public MachineFunctionPass {
MachineCodeEmitter &MCE;
+ BasicBlock *BB;
public:
SparcV9CodeEmitter(MachineCodeEmitter &M) : MCE(M) {}
Index: llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp
diff -u llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.2 llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.3
--- llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.2 Tue May 27 16:45:05 2003
+++ llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp Tue May 27 17:41:44 2003
@@ -30,8 +30,7 @@
} else if (MO.isImmediate()) {
return MO.getImmedValue();
} else if (MO.isPCRelativeDisp()) {
- // FIXME!!!
- //return MO.getPCRelativeDisp();
+ MCE->saveBBreference(currBB, MO);
return 0;
} else {
assert(0 && "Unknown type of MachineOperand");
@@ -55,6 +54,7 @@
}
void SparcV9CodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
+ currBB = MBB.getBasicBlock();
MCE.startBasicBlock(MBB);
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I)
emitInstruction(**I);
From brukman at cs.uiuc.edu Tue May 27 17:44:00 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 17:44:00 2003
Subject: [llvm-commits] CVS: llvm/lib/CodeGen/MachineCodeEmitter.cpp
Message-ID: <200305272243.RAA31425@zion.cs.uiuc.edu>
Changes in directory llvm/lib/CodeGen:
MachineCodeEmitter.cpp updated: 1.5 -> 1.6
---
Log message:
Added a debugging code emitter that prints code to a file, debug to std::cerr,
and passes the real code to a memory-outputting code emitter. This may be
removed at a later point in development.
---
Diffs of the changes:
Index: llvm/lib/CodeGen/MachineCodeEmitter.cpp
diff -u llvm/lib/CodeGen/MachineCodeEmitter.cpp:1.5 llvm/lib/CodeGen/MachineCodeEmitter.cpp:1.6
--- llvm/lib/CodeGen/MachineCodeEmitter.cpp:1.5 Thu May 8 22:27:41 2003
+++ llvm/lib/CodeGen/MachineCodeEmitter.cpp Tue May 27 17:43:19 2003
@@ -8,6 +8,7 @@
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/Function.h"
#include
+#include
namespace {
struct DebugMachineCodeEmitter : public MachineCodeEmitter {
@@ -58,4 +59,124 @@
///
MachineCodeEmitter *MachineCodeEmitter::createDebugMachineCodeEmitter() {
return new DebugMachineCodeEmitter();
+}
+
+namespace {
+ class FilePrinterMachineCodeEmitter : public MachineCodeEmitter {
+ std::ofstream f, actual;
+ std::ostream &o;
+ MachineCodeEmitter *MCE;
+ unsigned counter;
+ bool mustClose;
+ unsigned values[4];
+
+ public:
+ FilePrinterMachineCodeEmitter() :
+ f("lli.out"), o(f), counter(0), mustClose(true)
+ {
+ if (! f.good()) {
+ std::cerr << "Cannot open 'lli.out' for writing\n";
+ abort();
+ }
+ openActual();
+ }
+
+ FilePrinterMachineCodeEmitter(MachineCodeEmitter &M, std::ostream &os) :
+ o(os), MCE(&M), counter(0)
+ {
+ FilePrinterMachineCodeEmitter();
+ mustClose = false;
+ openActual();
+ }
+
+ ~FilePrinterMachineCodeEmitter() {
+ o << "\n";
+ actual.close();
+ if (mustClose) f.close();
+ }
+
+ void openActual() {
+ actual.open("lli.actual.obj");
+ if (! actual.good()) {
+ std::cerr << "Cannot open 'lli.actual.obj' for writing\n";
+ abort();
+ }
+ }
+
+ void startFunction(MachineFunction &F) {
+ // resolve any outstanding calls
+ if (MCE) MCE->startFunction(F);
+ }
+ void finishFunction(MachineFunction &F) {
+ if (MCE) MCE->finishFunction(F);
+ }
+
+ void startBasicBlock(MachineBasicBlock &BB) {
+ // if any instructions were waiting for the address of this block,
+ // let them fix their addresses now
+ if (MCE) MCE->startBasicBlock(BB);
+ }
+
+ void startFunctionStub(const Function &F, unsigned StubSize) {
+ //
+ if (MCE) MCE->startFunctionStub(F, StubSize);
+ }
+
+ void *finishFunctionStub(const Function &F) {
+ if (MCE) return MCE->finishFunctionStub(F);
+ else return 0;
+ }
+
+ void emitByte(unsigned char B) {
+ if (MCE) MCE->emitByte(B);
+
+ values[counter] = (unsigned int) B;
+ if (++counter % 4 == 0 && counter != 0) {
+ o << std::hex;
+ for (unsigned i=0; i<4; ++i) {
+ if (values[i] < 16) o << "0";
+ o << values[i] << " ";
+ actual << values[i];
+ }
+ actual.flush();
+
+ o << std::dec << "\t";
+ for (unsigned i=0; i<4; ++i) {
+ for (int j=7; j>=0; --j) {
+ o << ((values[i] >> j) & 1);
+ }
+ o << " ";
+ }
+
+ o << "\n";
+
+ unsigned instr = 0;
+ for (unsigned i=0; i<4; ++i)
+ instr |= values[i] << (i*8);
+
+ o << "--- * --- * --- * --- * ---\n";
+ counter %= 4;
+ }
+ }
+ void emitPCRelativeDisp(Value *V) {
+ // put block in mapping BB -> { instr, address }. when BB is beginning to
+ // output, find instr, set disp, overwrite instr at addr using the
+ // unsigned value gotten from emitter
+ }
+
+ void emitGlobalAddress(GlobalValue *V, bool isPCRelative) {
+ if (MCE) MCE->emitGlobalAddress(V, isPCRelative);
+ }
+ void emitGlobalAddress(const std::string &Name, bool isPCRelative) {
+ if (MCE) MCE->emitGlobalAddress(Name, isPCRelative);
+ }
+
+ void emitFunctionConstantValueAddress(unsigned ConstantNum, int Offset) {
+ if (MCE) MCE->emitFunctionConstantValueAddress(ConstantNum, Offset);
+ }
+ };
+}
+
+MachineCodeEmitter *MachineCodeEmitter::createFilePrinterMachineCodeEmitter(MachineCodeEmitter &MCE) {
+ return new FilePrinterMachineCodeEmitter(MCE, std::cerr);
}
From brukman at cs.uiuc.edu Tue May 27 17:45:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 17:45:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInternals.h
Message-ID: <200305272244.RAA31963@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
SparcInternals.h updated: 1.86 -> 1.87
---
Log message:
Added the 'r' and 'i' annotations to instructions as their opcode names have
changed.
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/SparcInternals.h
diff -u llvm/lib/Target/Sparc/SparcInternals.h:1.86 llvm/lib/Target/Sparc/SparcInternals.h:1.87
--- llvm/lib/Target/Sparc/SparcInternals.h:1.86 Tue May 27 17:01:10 2003
+++ llvm/lib/Target/Sparc/SparcInternals.h Tue May 27 17:44:44 2003
@@ -90,14 +90,14 @@
bool ignore;
if (this->maxImmedConstant(opCode, ignore) != 0) {
// 1st store opcode
- assert(! this->isStore((MachineOpCode) V9::STB - 1)); //r
+ assert(! this->isStore((MachineOpCode) V9::STBr - 1));
// last store opcode
- assert(! this->isStore((MachineOpCode) V9::STXFSR + 1)); //i
+ assert(! this->isStore((MachineOpCode) V9::STXFSRi + 1));
if (opCode == V9::SETSW || opCode == V9::SETUW ||
opCode == V9::SETX || opCode == V9::SETHI)
return 0;
- if (opCode >= V9::STB && opCode <= V9::STXFSR) //r, i
+ if (opCode >= V9::STBr && opCode <= V9::STXFSRi)
return 2;
return 1;
}
From brukman at cs.uiuc.edu Tue May 27 17:49:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Tue May 27 17:49:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcV9CodeEmitter.h SparcV9CodeEmitter.cpp
Message-ID: <200305272248.RAA00699@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
SparcV9CodeEmitter.h updated: 1.2 -> 1.3
SparcV9CodeEmitter.cpp updated: 1.3 -> 1.4
---
Log message:
Fixed an error preventing compilation.
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/SparcV9CodeEmitter.h
diff -u llvm/lib/Target/Sparc/SparcV9CodeEmitter.h:1.2 llvm/lib/Target/Sparc/SparcV9CodeEmitter.h:1.3
--- llvm/lib/Target/Sparc/SparcV9CodeEmitter.h:1.2 Tue May 27 17:41:44 2003
+++ llvm/lib/Target/Sparc/SparcV9CodeEmitter.h Tue May 27 17:48:28 2003
@@ -10,7 +10,7 @@
class SparcV9CodeEmitter : public MachineFunctionPass {
MachineCodeEmitter &MCE;
- BasicBlock *BB;
+ BasicBlock *currBB;
public:
SparcV9CodeEmitter(MachineCodeEmitter &M) : MCE(M) {}
Index: llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp
diff -u llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.3 llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.4
--- llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.3 Tue May 27 17:41:44 2003
+++ llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp Tue May 27 17:48:28 2003
@@ -30,7 +30,7 @@
} else if (MO.isImmediate()) {
return MO.getImmedValue();
} else if (MO.isPCRelativeDisp()) {
- MCE->saveBBreference(currBB, MO);
+ //MCE.saveBBreference(currBB, MO);
return 0;
} else {
assert(0 && "Unknown type of MachineOperand");
From jstanley at cs.uiuc.edu Wed May 28 08:53:01 2003
From: jstanley at cs.uiuc.edu (Joel Stanley)
Date: Wed May 28 08:53:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/Inst/lib/SparcInstManip.cpp
Message-ID: <200305281352.IAA17785@trinity.cs.uiuc.edu>
Changes in directory llvm/lib/Reoptimizer/Inst/lib:
SparcInstManip.cpp updated: 1.15 -> 1.16
---
Log message:
---
Diffs of the changes:
Index: llvm/lib/Reoptimizer/Inst/lib/SparcInstManip.cpp
diff -u llvm/lib/Reoptimizer/Inst/lib/SparcInstManip.cpp:1.15 llvm/lib/Reoptimizer/Inst/lib/SparcInstManip.cpp:1.16
--- llvm/lib/Reoptimizer/Inst/lib/SparcInstManip.cpp:1.15 Sun May 18 22:00:38 2003
+++ llvm/lib/Reoptimizer/Inst/lib/SparcInstManip.cpp Wed May 28 08:52:41 2003
@@ -411,8 +411,8 @@
// NB: Clearing PROT_WRITE here will result in subsequent valloc/memalign calls
// segfaulting. Apparently, write access to the page is still needed for later heap
- // allocations from the same page, although the requirement of write access is
- // somewhat unclear.
+ // allocations from the same page, although the reasons why write access are somewhat
+ // unclear.
setPageBits(heapSlot, numHeapBytes, PROT_READ | PROT_WRITE | PROT_EXEC);
From jstanley at cs.uiuc.edu Wed May 28 08:54:01 2003
From: jstanley at cs.uiuc.edu (Joel Stanley)
Date: Wed May 28 08:54:01 2003
Subject: [llvm-commits] CVS: llvm/include/llvm/Reoptimizer/BinInterface/sparc9.h
Message-ID: <200305281353.IAA17815@trinity.cs.uiuc.edu>
Changes in directory llvm/include/llvm/Reoptimizer/BinInterface:
sparc9.h updated: 1.12 -> 1.13
---
Log message:
---
Diffs of the changes:
Index: llvm/include/llvm/Reoptimizer/BinInterface/sparc9.h
diff -u llvm/include/llvm/Reoptimizer/BinInterface/sparc9.h:1.12 llvm/include/llvm/Reoptimizer/BinInterface/sparc9.h:1.13
--- llvm/include/llvm/Reoptimizer/BinInterface/sparc9.h:1.12 Tue Apr 15 16:32:53 2003
+++ llvm/include/llvm/Reoptimizer/BinInterface/sparc9.h Wed May 28 08:53:48 2003
@@ -443,9 +443,25 @@
MK_FLD(INSTR_X, 1) | \
MK_FLD(INSTR_SHCNT64, shcnt))
+#define MK_STORE_IMM(srcreg, basereg, offset) \
+ (MK_FLD(INSTR_OP, OP_3) | \
+ MK_FLD(INSTR_RD, srcreg) | \
+ MK_FLD(INSTR_OP3, OP3_STX) | \
+ MK_FLD(INSTR_RS1, basereg) | \
+ MK_FLD(INSTR_I, 1) | \
+ MK_FLD(INSTR_SIMM13, offset))
+
+#define MK_LOAD_IMM(destreg, basereg, offset) \
+ (MK_FLD(INSTR_OP, OP_3) | \
+ MK_FLD(INSTR_RD, destreg) | \
+ MK_FLD(INSTR_OP3, OP3_LDX) | \
+ MK_FLD(INSTR_RS1, basereg) | \
+ MK_FLD(INSTR_I, 1) | \
+ MK_FLD(INSTR_SIMM13, offset))
+
// Construct save instruction
-#define MK_SAVE(dreg, sreg, imm) \
+#define MK_SAVE_IMM(dreg, sreg, imm) \
(MK_FLD(INSTR_OP, OP_2) | \
MK_FLD(INSTR_RD, dreg) | \
MK_FLD(INSTR_OP3, OP3_SAVE) | \
@@ -453,10 +469,26 @@
MK_FLD(INSTR_I, 1) | \
MK_FLD(INSTR_SIMM13, imm))
-#define MK_RESTORE(dreg, sreg, imm) \
+#define MK_SAVE_REG(dreg, sreg1, sreg2) \
+ (MK_FLD(INSTR_OP, OP_2) | \
+ MK_FLD(INSTR_RD, dreg) | \
+ MK_FLD(INSTR_OP3, OP3_SAVE) | \
+ MK_FLD(INSTR_RS1, sreg1) | \
+ MK_FLD(INSTR_I, 0) | \
+ MK_FLD(INSTR_RS2, sreg2))
+
+#define MK_RESTORE_IMM(dreg, sreg, imm) \
(MK_FLD(INSTR_OP, OP_2) | \
MK_FLD(INSTR_RD, dreg) | \
MK_FLD(INSTR_OP3, OP3_RESTORE) | \
+ MK_FLD(INSTR_RS1, sreg) | \
+ MK_FLD(INSTR_I, 1) | \
+ MK_FLD(INSTR_SIMM13, imm))
+
+#define MK_JMPL_INDIRECT(dreg, sreg, imm) \
+ (MK_FLD(INSTR_OP, OP_2) | \
+ MK_FLD(INSTR_RD, dreg) | \
+ MK_FLD(INSTR_OP3, OP3_JMPL) | \
MK_FLD(INSTR_RS1, sreg) | \
MK_FLD(INSTR_I, 1) | \
MK_FLD(INSTR_SIMM13, imm))
From jstanley at cs.uiuc.edu Wed May 28 08:54:04 2003
From: jstanley at cs.uiuc.edu (Joel Stanley)
Date: Wed May 28 08:54:04 2003
Subject: [llvm-commits] CVS: llvm/include/llvm/Reoptimizer/TraceCache.h
Message-ID: <200305281353.IAA17807@trinity.cs.uiuc.edu>
Changes in directory llvm/include/llvm/Reoptimizer:
TraceCache.h updated: 1.7 -> 1.8
---
Log message:
---
Diffs of the changes:
Index: llvm/include/llvm/Reoptimizer/TraceCache.h
diff -u llvm/include/llvm/Reoptimizer/TraceCache.h:1.7 llvm/include/llvm/Reoptimizer/TraceCache.h:1.8
--- llvm/include/llvm/Reoptimizer/TraceCache.h:1.7 Fri Apr 4 14:28:23 2003
+++ llvm/include/llvm/Reoptimizer/TraceCache.h Wed May 28 08:53:48 2003
@@ -110,6 +110,9 @@
//remove trace starting with address n
void removeTrace(uint64_t n);
+ MemoryManager* getMemMgr() { return mm; }
+ VirtualMem* getVM() { return vm; }
+
VirtualMem *vm;
MemoryManager *mm;
};
From vadve at cs.uiuc.edu Wed May 28 08:55:00 2003
From: vadve at cs.uiuc.edu (Vikram Adve)
Date: Wed May 28 08:55:00 2003
Subject: [llvm-commits] CVS: llvm/test/Regression/LLC/2003-05-27-phifcmpd.ll 2003-05-27-useboolinotherbb.ll 2003-05-27-usefsubasbool.ll
Message-ID: <200305281354.IAA18811@psmith.cs.uiuc.edu>
Changes in directory llvm/test/Regression/LLC:
2003-05-27-phifcmpd.ll added (r1.1)
2003-05-27-useboolinotherbb.ll added (r1.1)
2003-05-27-usefsubasbool.ll added (r1.1)
---
Log message:
Three kinds of boolean values handled incorrectly:
-- setCC of FP type used by a Phi: have to save in reg.
-- setNE of FP type used by a branch: cannot use result directly in branch!
-- setCC used outside the same basic block: have to save in reg. for now
---
Diffs of the changes:
Index: llvm/test/Regression/LLC/2003-05-27-phifcmpd.ll
diff -c /dev/null llvm/test/Regression/LLC/2003-05-27-phifcmpd.ll:1.1
*** /dev/null Wed May 28 08:54:51 2003
--- llvm/test/Regression/LLC/2003-05-27-phifcmpd.ll Wed May 28 08:54:41 2003
***************
*** 0 ****
--- 1,71 ----
+ ;; Date: May 28, 2003.
+ ;; From: test/Programs/MultiSource/McCat-05-eks/QRfact.c
+ ;; Function: Matrix QRiterate(Matrix A, Matrix U)
+ ;;
+ ;; Error: llc produces an invalid register for the
+ ;; phi argument %tmp.213 produced by fcmpd:
+ ;;
+ ;; LLC Output:
+ ;;
+ ;; !****** Outputing Function: QRiterate_1 ******
+ ;;
+ ;; .section ".text"
+ ;; .align 4
+ ;; .global QRiterate_1
+ ;; .type QRiterate_1, 2
+ ;; QRiterate_1:
+ ;; .L_QRiterate_1_LL_0:
+ ;; save %o6, -192, %o6
+ ;; brgz %i0, .L_QRiterate_1_LL_1
+ ;; add %g0, %g0, %o0
+ ;; ba .L_QRiterate_1_LL_2
+ ;; nop
+ ;;
+ ;; .L_QRiterate_1_LL_1:
+ ;; sethi %lm(LLVMGlobal__2), %o1
+ ;; sethi %hh(LLVMGlobal__2), %o0
+ ;; or %o0, %hm(LLVMGlobal__2), %o0
+ ;; sllx %o0, 32, %o0
+ ;; or %o1, %o0, %o1
+ ;; or %o1, %lo(LLVMGlobal__2), %o1
+ ;; ldd [%o1+0], %f32
+ ;; fcmpd %fcc0, %f2, %f32
+ ;; ba .L_QRiterate_1_LL_2
+ ;; add , %g0, %o0
+ ;;
+ ;; .L_QRiterate_1_LL_2:
+ ;; brnz %o0, .L_QRiterate_1_LL_1
+ ;; nop
+ ;; ba .L_QRiterate_1_LL_3
+ ;; nop
+ ;;
+ ;; .L_QRiterate_1_LL_3:
+ ;; jmpl %i7+8, %g0
+ ;; restore %g0, 0, %g0
+ ;;
+ ;; .EndOf_QRiterate_1:
+ ;; .size QRiterate_1, .EndOf_QRiterate_1-QRiterate_1
+ ;;
+
+
+ target endian = big
+ target pointersize = 64
+
+ implementation ; Functions:
+
+ internal void %QRiterate(int %p.1, double %tmp.212) {
+ entry: ; No predecessors!
+ %tmp.184 = setgt int %p.1, 0 ; [#uses=1]
+ br bool %tmp.184, label %shortcirc_next.1, label %shortcirc_done.1
+
+ shortcirc_next.1: ; preds = %entry
+ %tmp.213 = setne double %tmp.212, 0.000000e+00
+ br label %shortcirc_done.1
+
+ shortcirc_done.1: ; preds = %entry, %shortcirc_next.1
+ %val.1 = phi bool [ false, %entry ], [ %tmp.213, %shortcirc_next.1 ]
+ br bool %val.1, label %shortcirc_next.1, label %exit.1
+
+ exit.1:
+ ret void
+ }
Index: llvm/test/Regression/LLC/2003-05-27-useboolinotherbb.ll
diff -c /dev/null llvm/test/Regression/LLC/2003-05-27-useboolinotherbb.ll:1.1
*** /dev/null Wed May 28 08:54:51 2003
--- llvm/test/Regression/LLC/2003-05-27-useboolinotherbb.ll Wed May 28 08:54:41 2003
***************
*** 0 ****
--- 1,63 ----
+ ;; Date: May 27, 2003.
+ ;; From: Variant of 2003-05-27-usefsubasbool.ll
+ ;;
+ ;; Error: llc fails to save a boolean value in a register (and later uses an
+ ;; invalid register in a BRNZ) for a boolean value
+ ;; used only by branches but in a different basic block.
+ ;;
+ ;; Cause: In SparcInstrSelection.cpp, for SetCC, when a result of setCC
+ ;; is used only for branches, it is not saved into an int. register.
+ ;; But if the boolean is used in a branch in a different basic block,
+ ;; that branch uses a BRNZ inst. instead of a branch-on-CC.
+ ;;
+ ;; LLC Output before fix:
+ ;; !****** Outputing Function: QRiterate_1 ******
+ ;;
+ ;; .section ".text"
+ ;; .align 4
+ ;; .global QRiterate_1
+ ;; .type QRiterate_1, 2
+ ;; QRiterate_1:
+ ;; .L_QRiterate_1_LL_0:
+ ;; save %o6, -192, %o6
+ ;; sethi %lm(LLVMGlobal__2), %o2
+ ;; sethi %hh(LLVMGlobal__2), %o1
+ ;; or %o1, %hm(LLVMGlobal__2), %o1
+ ;; sllx %o1, 32, %o1
+ ;; or %o2, %o1, %o2
+ ;; or %o2, %lo(LLVMGlobal__2), %o2
+ ;; ldd [%o2+0], %f32
+ ;; fcmpd %fcc0, %f0, %f32
+ ;; ba .L_QRiterate_1_LL_1
+ ;; nop
+ ;;
+ ;; .L_QRiterate_1_LL_1:
+ ;; brnz , .L_QRiterate_1_LL_1
+ ;; nop
+ ;; ba .L_QRiterate_1_LL_2
+ ;; nop
+ ;;
+ ;; .L_QRiterate_1_LL_2:
+ ;; jmpl %i7+8, %g0
+ ;; restore %g0, 0, %g0
+ ;;
+ ;; .EndOf_QRiterate_1:
+ ;; .size QRiterate_1, .EndOf_QRiterate_1-QRiterate_1
+ ;;
+
+ target endian = big
+ target pointersize = 64
+
+ implementation ; Functions:
+
+ internal void %QRiterate(double %tmp.212) {
+ entry: ; No predecessors!
+ %tmp.213 = setne double %tmp.212, 0.000000e+00
+ br label %shortcirc_next.1
+
+ shortcirc_next.1: ; preds = %entry
+ br bool %tmp.213, label %shortcirc_next.1, label %exit.1
+
+ exit.1:
+ ret void
+ }
Index: llvm/test/Regression/LLC/2003-05-27-usefsubasbool.ll
diff -c /dev/null llvm/test/Regression/LLC/2003-05-27-usefsubasbool.ll:1.1
*** /dev/null Wed May 28 08:54:51 2003
--- llvm/test/Regression/LLC/2003-05-27-usefsubasbool.ll Wed May 28 08:54:41 2003
***************
*** 0 ****
--- 1,63 ----
+ ;; Date: May 27, 2003.
+ ;; From: test/Programs/MultiSource/McCat-05-eks/QRfact.c
+ ;; Function: Matrix QRiterate(Matrix A, Matrix U)
+ ;;
+ ;; Error: llc produces an invalid register for the
+ ;; a boolean value computed using setne with a double.
+ ;;
+ ;; Cause: In SparcInstrSelection.cpp, for SetCC, when a result of setne
+ ;; is used for a branch, it can generate a "branch-on-integer-register"
+ ;; for integer registers. In that case, it never saves the value of
+ ;; the boolean result. It was attempting to do the same thing for an
+ ;; FP compare!
+ ;;
+ ;; LLC Output:
+ ;; !****** Outputing Function: QRiterate_1 ******
+ ;;
+ ;; .section ".text"
+ ;; .align 4
+ ;; .global QRiterate_1
+ ;; .type QRiterate_1, 2
+ ;; QRiterate_1:
+ ;; .L_QRiterate_1_LL_0:
+ ;; save %o6, -192, %o6
+ ;; sethi %hh(LLVMGlobal__2), %o1
+ ;; sethi %lm(LLVMGlobal__2), %o0
+ ;; or %o1, %hm(LLVMGlobal__2), %o1
+ ;; sllx %o1, 32, %o1
+ ;; or %o0, %o1, %o0
+ ;; or %o0, %lo(LLVMGlobal__2), %o0
+ ;; ldd [%o0+0], %f32
+ ;; ba .L_QRiterate_1_LL_1
+ ;; fcmpd %fcc0, %f0, %f32
+ ;;
+ ;; .L_QRiterate_1_LL_1:
+ ;; brnz , .L_QRiterate_1_LL_1
+ ;; nop
+ ;; ba .L_QRiterate_1_LL_2
+ ;; nop
+ ;;
+ ;; .L_QRiterate_1_LL_2:
+ ;; jmpl %i7+8, %g0
+ ;; restore %g0, 0, %g0
+ ;;
+ ;; .EndOf_QRiterate_1:
+ ;; .size QRiterate_1, .EndOf_QRiterate_1-QRiterate_1
+ ;;
+
+ target endian = big
+ target pointersize = 64
+
+ implementation ; Functions:
+
+ internal void %QRiterate(double %tmp.212) {
+ entry: ; No predecessors!
+ br label %shortcirc_next.1
+
+ shortcirc_next.1: ; preds = %entry
+ %tmp.213 = setne double %tmp.212, 0.000000e+00
+ br bool %tmp.213, label %shortcirc_next.1, label %exit.1
+
+ exit.1:
+ ret void
+ }
From jstanley at cs.uiuc.edu Wed May 28 09:49:05 2003
From: jstanley at cs.uiuc.edu (Joel Stanley)
Date: Wed May 28 09:49:05 2003
Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/Inst/lib/Phase1/Phase1.cpp
Message-ID: <200305281425.JAA19011@trinity.cs.uiuc.edu>
Changes in directory llvm/lib/Reoptimizer/Inst/lib/Phase1:
Phase1.cpp updated: 1.26.2.1 -> 1.26.2.2
---
Log message:
Testing CVS branch checkin.
---
Diffs of the changes:
Index: llvm/lib/Reoptimizer/Inst/lib/Phase1/Phase1.cpp
diff -u llvm/lib/Reoptimizer/Inst/lib/Phase1/Phase1.cpp:1.26.2.1 llvm/lib/Reoptimizer/Inst/lib/Phase1/Phase1.cpp:1.26.2.2
--- llvm/lib/Reoptimizer/Inst/lib/Phase1/Phase1.cpp:1.26.2.1 Wed May 28 09:21:12 2003
+++ llvm/lib/Reoptimizer/Inst/lib/Phase1/Phase1.cpp Wed May 28 09:25:21 2003
@@ -54,8 +54,6 @@
bool run(Module& m);
private:
- // TESTING CVS BRANCHING, JUST IGNORE...
-
// placeholder pairs holds: glob volatile ptr, glob temporary variable ptr
typedef std::pair PlaceholderPair;
From jstanley at cs.uiuc.edu Wed May 28 10:00:48 2003
From: jstanley at cs.uiuc.edu (Joel Stanley)
Date: Wed May 28 10:00:48 2003
Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/Inst/lib/Phase1/Phase1.cpp
Message-ID: <200305281421.JAA18697@trinity.cs.uiuc.edu>
Changes in directory llvm/lib/Reoptimizer/Inst/lib/Phase1:
Phase1.cpp updated: 1.26 -> 1.26.2.1
---
Log message:
Testing CVS branch checkin.
---
Diffs of the changes:
Index: llvm/lib/Reoptimizer/Inst/lib/Phase1/Phase1.cpp
diff -u llvm/lib/Reoptimizer/Inst/lib/Phase1/Phase1.cpp:1.26 llvm/lib/Reoptimizer/Inst/lib/Phase1/Phase1.cpp:1.26.2.1
--- llvm/lib/Reoptimizer/Inst/lib/Phase1/Phase1.cpp:1.26 Thu May 22 22:26:13 2003
+++ llvm/lib/Reoptimizer/Inst/lib/Phase1/Phase1.cpp Wed May 28 09:21:12 2003
@@ -54,6 +54,8 @@
bool run(Module& m);
private:
+ // TESTING CVS BRANCHING, JUST IGNORE...
+
// placeholder pairs holds: glob volatile ptr, glob temporary variable ptr
typedef std::pair PlaceholderPair;
From gaeke at cs.uiuc.edu Wed May 28 12:42:00 2003
From: gaeke at cs.uiuc.edu (Brian Gaeke)
Date: Wed May 28 12:42:00 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/Makefile
Message-ID: <200305281741.MAA31693@gally.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
Makefile updated: 1.15 -> 1.16
---
Log message:
Add dependency to make TableGen rule fire.
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/Makefile
diff -u llvm/lib/Target/Sparc/Makefile:1.15 llvm/lib/Target/Sparc/Makefile:1.16
--- llvm/lib/Target/Sparc/Makefile:1.15 Tue May 27 17:04:38 2003
+++ llvm/lib/Target/Sparc/Makefile Wed May 28 12:41:09 2003
@@ -3,6 +3,8 @@
ExtraSource = Debug/Sparc.burm.cpp
+SparcV9CodeEmitter.cpp: SparcV9CodeEmitter.inc
+
SparcV9CodeEmitter.inc: SparcV9.td
@echo "TableGen-erating $@"
cpp -P SparcV9.td | tblgen -gen-emitter > SparcV9CodeEmitter.inc
From brukman at cs.uiuc.edu Wed May 28 12:50:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Wed May 28 12:50:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcV9.td
Message-ID: <200305281749.MAA14126@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
SparcV9.td updated: 1.2 -> 1.3
---
Log message:
Fixed ordering of elements in instructions: although the binary instructions
list (rd, rs1, imm), in that order (bit-wise), the actual assembly syntax is
instr rd, imm, rs1, and that is how they are constructed in the instruction
selector. This fixes the discrepancy.
Also fixed some comments along the same lines and fixed page numbers referring
to where instructions are described in the Sparc manual.
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/SparcV9.td
diff -u llvm/lib/Target/Sparc/SparcV9.td:1.2 llvm/lib/Target/Sparc/SparcV9.td:1.3
--- llvm/lib/Target/Sparc/SparcV9.td:1.2 Tue May 27 15:03:29 2003
+++ llvm/lib/Target/Sparc/SparcV9.td Wed May 28 12:49:29 2003
@@ -140,32 +140,59 @@
set Inst{24-19} = op3;
}
-// F3_rs1 - Common superclass of instructions that use rs1
-class F3_rs1 : F3 {
+class F3_rd : F3 {
+ bits<5> rd;
+ set Inst{29-25} = rd;
+}
+
+class F3_rdsimm13 : F3_rd {
+ bits<13> simm13;
+ set Inst{12-0} = simm13;
+}
+
+class F3_rdsimm13rs1 : F3_rdsimm13 {
bits<5> rs1;
set Inst{18-14} = rs1;
}
-// F3_rs1rd - Common superclass of instructions that use rs1 & rd...
-class F3_rs1rd : F3 {
- // Added rs1 here manually to have rd appear before rs1
- // Formerly inherited directly from F3_rs1
- bits<5> rd;
+// F3_rdrs1 - Common superclass of instructions that use rd & rs1
+class F3_rdrs1 : F3_rd {
bits<5> rs1;
- set Inst{29-25} = rd;
set Inst{18-14} = rs1;
}
-// F3_rs1rdrs2 - Common superclass of instructions with rs1, rd, & rs2 fields
-class F3_rs1rdrs2 : F3_rs1rd {
+// F3_rs1rdrs2 - Common superclass of instructions with rd, rs1, & rs2 fields
+class F3_rdrs1rs2 : F3_rdrs1 {
+ bits<5> rs2;
+ set Inst{4-0} = rs2;
+}
+
+// F3_rs1 - Common class of instructions that do not have an rd field,
+// but start at rs1
+class F3_rs1 : F3 {
+ bits<5> rs1;
+ //set Inst{29-25} = dontcare;
+ set Inst{18-14} = rs1;
+}
+
+// F3_rs1rs2 - Common class of instructions that only have rs1 and rs2 fields
+class F3_rs1rs2 : F3_rs1 {
bits<5> rs2;
+ //set Inst{12-5} = dontcare;
set Inst{4-0} = rs2;
}
+// F3_rs1rs2 - Common class of instructions that only have rs1 and rs2 fields
+class F3_rs1simm13 : F3_rs1 {
+ bits<13> simm13;
+ set Inst{12-0} = simm13;
+}
+
+
// Specific F3 classes...
//
-class F3_1 opVal, bits<6> op3val, string name> : F3_rs1rdrs2 {
+class F3_1 opVal, bits<6> op3val, string name> : F3_rdrs1rs2 {
set op = opVal;
set op3 = op3val;
set Name = name;
@@ -173,28 +200,21 @@
//set Inst{12-5} = dontcare;
}
-class F3_2 opVal, bits<6> op3val, string name> : F3_rs1rd {
- bits<13> simm;
-
+class F3_2 opVal, bits<6> op3val, string name> : F3_rdsimm13rs1 {
set op = opVal;
set op3 = op3val;
set Name = name;
set Inst{13} = 1; // i field = 1
- set Inst{12-0} = simm;
}
-class F3_3 opVal, bits<6> op3val, string name> : F3_rs1 {
- bits<5> rs2;
+class F3_3 opVal, bits<6> op3val, string name> : F3_rs1rs2 {
set op = opVal;
set op3 = op3val;
set Name = name;
- //set Inst{29-25} = dontcare;
set Inst{13} = 0;
- //set Inst{12-5} = dontcare;
- set Inst{4-0} = rs2;
}
-class F3_4 opVal, bits<6> op3Val, string name> : F3_rs1 {
+class F3_4 opVal, bits<6> op3Val, string name> : F3_rs1simm13 {
bits<13> simm;
set op = opVal;
set op3 = op3Val;
@@ -204,7 +224,7 @@
set Inst{12-0} = simm;
}
-class F3_11 opVal, bits<6> op3Val, string name> : F3_rs1rdrs2 {
+class F3_11 opVal, bits<6> op3Val, string name> : F3_rdrs1rs2 {
bit x;
set op = opVal;
set op3 = op3Val;
@@ -235,7 +255,7 @@
}
class F3_14 opVal, bits<6> op3val,
- bits<9> opfval, string name> : F3_rs1rdrs2 {
+ bits<9> opfval, string name> : F3_rdrs1rs2 {
set op = opVal;
set op3 = op3val;
set Name = name;
@@ -244,7 +264,7 @@
}
class F3_16 opVal, bits<6> op3val,
- bits<9> opfval, string name> : F3_rs1rdrs2 {
+ bits<9> opfval, string name> : F3_rdrs1rs2 {
set op = opVal;
set op3 = op3val;
set Name = name;
@@ -263,17 +283,17 @@
// Instruction list...
//
-// Section A.2: p161
+// Section A.2: Add - p137
def ADDr : F3_1<2, 0b000000, "add">; // add r, r, r
-def ADDi : F3_2<2, 0b000000, "add">; // add r, r, i
+def ADDi : F3_2<2, 0b000000, "add">; // add r, i, r
def ADDccr : F3_1<2, 0b010000, "addcc">; // addcc r, r, r
-def ADDcci : F3_2<2, 0b010000, "addcc">; // addcc r, r, i
+def ADDcci : F3_2<2, 0b010000, "addcc">; // addcc r, i, r
def ADDCr : F3_1<2, 0b001000, "addC">; // addC r, r, r
-def ADDCi : F3_2<2, 0b001000, "addC">; // addC r, r, i
+def ADDCi : F3_2<2, 0b001000, "addC">; // addC r, i, r
def ADDCccr : F3_1<2, 0b011000, "addCcc">; // addCcc r, r, r
-def ADDCcci : F3_2<2, 0b011000, "addCcc">; // addCcc r, r, i
+def ADDCcci : F3_2<2, 0b011000, "addCcc">; // addCcc r, i, r
-// Section A.3: p162
+// Section A.3: Branch on Integer Register with Prediction - p162
set op2 = 0b011 in {
def BRZ : F2_4<0b001, "brz">; // Branch on rs1 == 0
def BRLEZ : F2_4<0b010, "brlez">; // Branch on rs1 <= 0
From brukman at cs.uiuc.edu Wed May 28 13:28:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Wed May 28 13:28:01 2003
Subject: [llvm-commits] CVS: llvm/lib/CodeGen/MachineCodeEmitter.cpp
Message-ID: <200305281827.NAA14581@zion.cs.uiuc.edu>
Changes in directory llvm/lib/CodeGen:
MachineCodeEmitter.cpp updated: 1.6 -> 1.7
---
Log message:
Correctly write out binary data as chars, before they're cast to ints.
---
Diffs of the changes:
Index: llvm/lib/CodeGen/MachineCodeEmitter.cpp
diff -u llvm/lib/CodeGen/MachineCodeEmitter.cpp:1.6 llvm/lib/CodeGen/MachineCodeEmitter.cpp:1.7
--- llvm/lib/CodeGen/MachineCodeEmitter.cpp:1.6 Tue May 27 17:43:19 2003
+++ llvm/lib/CodeGen/MachineCodeEmitter.cpp Wed May 28 13:27:19 2003
@@ -129,6 +129,7 @@
void emitByte(unsigned char B) {
if (MCE) MCE->emitByte(B);
+ actual << B; actual.flush();
values[counter] = (unsigned int) B;
if (++counter % 4 == 0 && counter != 0) {
@@ -136,9 +137,7 @@
for (unsigned i=0; i<4; ++i) {
if (values[i] < 16) o << "0";
o << values[i] << " ";
- actual << values[i];
}
- actual.flush();
o << std::dec << "\t";
for (unsigned i=0; i<4; ++i) {
From brukman at cs.uiuc.edu Wed May 28 13:30:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Wed May 28 13:30:01 2003
Subject: [llvm-commits] CVS: llvm/utils/TableGen/CodeEmitterGen.cpp
Message-ID: <200305281829.NAA14625@zion.cs.uiuc.edu>
Changes in directory llvm/utils/TableGen:
CodeEmitterGen.cpp updated: 1.3 -> 1.4
---
Log message:
Output the opcode name of the instruction being emitted to cerr.
---
Diffs of the changes:
Index: llvm/utils/TableGen/CodeEmitterGen.cpp
diff -u llvm/utils/TableGen/CodeEmitterGen.cpp:1.3 llvm/utils/TableGen/CodeEmitterGen.cpp:1.4
--- llvm/utils/TableGen/CodeEmitterGen.cpp:1.3 Tue May 27 17:29:02 2003
+++ llvm/utils/TableGen/CodeEmitterGen.cpp Wed May 28 13:29:10 2003
@@ -27,7 +27,8 @@
I != E; ++I)
{
Record *R = *I;
- o << " case " << Namespace << R->getName() << ": {\n";
+ o << " case " << Namespace << R->getName() << ": {\n"
+ << " std::cerr << \"Emitting " << R->getName() << "\\n\";\n";
const RecordVal *InstVal = R->getValue("Inst");
Init *InitVal = InstVal->getValue();
@@ -49,9 +50,9 @@
o << "0";
}
}
- o << "\n\n";
+ o << "\n";
- o << " // " << *InstVal << "\n\n";
+ o << " // " << *InstVal << "\n";
o << " Value = " << Value << "U;\n\n";
// Loop over all of the fields in the instruction adding in any
From brukman at cs.uiuc.edu Wed May 28 13:45:02 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Wed May 28 13:45:02 2003
Subject: [llvm-commits] CVS: llvm/tools/lli/JIT/SparcEmitter.cpp
Message-ID: <200305281844.NAA15255@zion.cs.uiuc.edu>
Changes in directory llvm/tools/lli/JIT:
SparcEmitter.cpp updated: 1.1 -> 1.2
---
Log message:
mmap() seems to be failing on Sparc, so just use malloc()/free() .
---
Diffs of the changes:
Index: llvm/tools/lli/JIT/SparcEmitter.cpp
diff -u llvm/tools/lli/JIT/SparcEmitter.cpp:1.1 llvm/tools/lli/JIT/SparcEmitter.cpp:1.2
--- llvm/tools/lli/JIT/SparcEmitter.cpp:1.1 Tue May 27 16:40:39 2003
+++ llvm/tools/lli/JIT/SparcEmitter.cpp Wed May 28 13:44:38 2003
@@ -32,8 +32,16 @@
std::pair > > BBRefs;
std::map BBLocations;
std::vector ConstantPoolAddresses;
+ std::vector funcMemory;
public:
SparcEmitter(VM &vm) : TheVM(vm) {}
+ ~SparcEmitter() {
+ while (! funcMemory.empty()) {
+ void* addr = funcMemory.back();
+ free(addr);
+ funcMemory.pop_back();
+ }
+ }
virtual void startFunction(MachineFunction &F);
virtual void finishFunction(MachineFunction &F);
@@ -49,9 +57,11 @@
int Offset);
virtual void saveBBreference(BasicBlock *BB, MachineInstr &MI);
+
private:
void emitAddress(void *Addr, bool isPCRelative);
+ void* getMemory(unsigned NumPages);
};
}
@@ -66,22 +76,36 @@
// FIXME: This should be rewritten to support a real memory manager for
// executable memory pages!
-static void *getMemory(unsigned NumPages) {
- return mmap(0, 4096*NumPages, PROT_READ|PROT_WRITE|PROT_EXEC,
- MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
+void * SparcEmitter::getMemory(unsigned NumPages) {
+#if 0
+ void *pa = mmap(0, 4096*NumPages, PROT_READ|PROT_WRITE|PROT_EXEC,
+ MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
+ if (pa == MAP_FAILED) {
+ perror("mmap");
+ abort();
+ }
+#endif
+ void *pa = malloc(4096*NumPages);
+ if (!pa) {
+ perror("malloc");
+ abort();
+ }
+ funcMemory.push_back(pa);
+ return pa;
}
void SparcEmitter::startFunction(MachineFunction &F) {
CurBlock = (unsigned char *)getMemory(8);
+ std::cerr << "Starting function " << F.getFunction()->getName() << "\n";
CurByte = CurBlock; // Start writing at the beginning of the fn.
TheVM.addGlobalMapping(F.getFunction(), CurBlock);
}
void SparcEmitter::finishFunction(MachineFunction &F) {
ConstantPoolAddresses.clear();
+ // Re-write branches to BasicBlocks for the entire function
for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) {
- // Re-write branches to BasicBlocks for the entire function
unsigned Location = BBLocations[BBRefs[i].first];
unsigned *Ref = BBRefs[i].second.first;
MachineInstr *MI = BBRefs[i].second.second;
@@ -149,6 +173,7 @@
// BasicBlock -> pair
// when the BB is emitted, machineinstr is modified with then-currbyte,
// processed with MCE, and written out at memloc.
+// Should be called by the emitter if its outputting a PCRelative disp
void SparcEmitter::saveBBreference(BasicBlock *BB, MachineInstr &MI) {
BBRefs.push_back(std::make_pair(BB, std::make_pair((unsigned*)CurByte, &MI)));
}
From brukman at cs.uiuc.edu Wed May 28 22:32:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Wed May 28 22:32:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcV9_F2.td SparcV9_F3.td SparcV9_F4.td SparcV9_Reg.td SparcV9.td
Message-ID: <200305290331.WAA23025@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
SparcV9_F2.td added (r1.1)
SparcV9_F3.td added (r1.1)
SparcV9_F4.td added (r1.1)
SparcV9_Reg.td added (r1.1)
SparcV9.td updated: 1.3 -> 1.4
---
Log message:
* Broke up SparcV9.td into separate files as it was getting unmanageable
* Added some Format 4 classes, but not instructions
* Added notes on missing sections with FIXMEs
* Added RDCCR instr
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/SparcV9_F2.td
diff -c /dev/null llvm/lib/Target/Sparc/SparcV9_F2.td:1.1
*** /dev/null Wed May 28 22:31:53 2003
--- llvm/lib/Target/Sparc/SparcV9_F2.td Wed May 28 22:31:43 2003
***************
*** 0 ****
--- 1,64 ----
+ //===- Sparc.td - Target Description for Sparc V9 Target --------*- C++ -*-===//
+ // vim:ft=cpp
+ //===----------------------------------------------------------------------===//
+
+ //===----------------------------------------------------------------------===//
+ // Format #2 classes
+ //
+ class F2 : InstV9 { // Format 2 instructions
+ bits<3> op2;
+ set op = 0; // Op = 0
+ set Inst{24-22} = op2;
+ }
+
+ // Format 2.1 instructions
+ class F2_1 : F2 {
+ bits<5> rd;
+ bits<22> imm;
+
+ set Name = name;
+ set Inst{29-25} = rd;
+ set Inst{21-0} = imm;
+ }
+
+ class F2_br : F2 { // Format 2 Branch instruction
+ bit annul; // All branches have an annul bit
+ set Inst{29} = annul;
+ set isBranch = 1; // All instances are branch instructions
+ }
+
+ class F2_2 cond, string name> : F2_br { // Format 2.2 instructions
+ bits<22> disp;
+
+ set Name = name;
+ set Inst{28-25} = cond;
+ set Inst{21-0} = disp;
+ }
+
+ class F2_3 cond, string name> : F2_br { // Format 2.3 instructions
+ bits<2> cc;
+ bits<19> disp;
+ bit predict;
+
+ set Name = name;
+ set Inst{28-25} = cond;
+ set Inst{21-20} = cc;
+ set Inst{19} = predict;
+ set Inst{18-0} = disp;
+ }
+
+ class F2_4 rcond, string name> : F2_br { // Format 2.4 instructions
+ // Variables exposed by the instruction...
+ bit predict;
+ bits<5> rs1;
+ bits<16> disp;
+
+ set Name = name;
+ set Inst{28} = 0;
+ set Inst{27-25} = rcond;
+ // Inst{24-22} = op2 field
+ set Inst{21-20} = disp{15-14};
+ set Inst{19} = predict;
+ set Inst{18-14} = rs1;
+ set Inst{13-0 } = disp{13-0};
+ }
Index: llvm/lib/Target/Sparc/SparcV9_F3.td
diff -c /dev/null llvm/lib/Target/Sparc/SparcV9_F3.td:1.1
*** /dev/null Wed May 28 22:31:53 2003
--- llvm/lib/Target/Sparc/SparcV9_F3.td Wed May 28 22:31:43 2003
***************
*** 0 ****
--- 1,171 ----
+ //===- Sparc.td - Target Description for Sparc V9 Target --------*- C++ -*-===//
+ // vim:ft=cpp
+ //===----------------------------------------------------------------------===//
+
+ //===----------------------------------------------------------------------===//
+ // Format #3 classes
+ //
+
+ // F3 - Common superclass of all F3 instructions. All instructions have an op3
+ // field.
+ class F3 : InstV9 {
+ bits<6> op3;
+ set op{1} = 1; // Op = 2 or 3
+ set Inst{24-19} = op3;
+ }
+
+ class F3_rd : F3 {
+ bits<5> rd;
+ set Inst{29-25} = rd;
+ }
+
+ class F3_rdsimm13 : F3_rd {
+ bits<13> simm13;
+ set Inst{12-0} = simm13;
+ }
+
+ class F3_rdsimm13rs1 : F3_rdsimm13 {
+ bits<5> rs1;
+ set Inst{18-14} = rs1;
+ }
+
+ // F3_rdrs1 - Common superclass of instructions that use rd & rs1
+ class F3_rdrs1 : F3_rd {
+ bits<5> rs1;
+ set Inst{18-14} = rs1;
+ }
+
+ // F3_rs1rdrs2 - Common superclass of instructions with rd, rs1, & rs2 fields
+ class F3_rdrs1rs2 : F3_rdrs1 {
+ bits<5> rs2;
+ set Inst{4-0} = rs2;
+ }
+
+ // F3_rs1 - Common class of instructions that do not have an rd field,
+ // but start at rs1
+ class F3_rs1 : F3 {
+ bits<5> rs1;
+ //set Inst{29-25} = dontcare;
+ set Inst{18-14} = rs1;
+ }
+
+ // F3_rs1rs2 - Common class of instructions that only have rs1 and rs2 fields
+ class F3_rs1rs2 : F3_rs1 {
+ bits<5> rs2;
+ //set Inst{12-5} = dontcare;
+ set Inst{4-0} = rs2;
+ }
+
+ // F3_rs1simm13 - Common class of instructions that only have rs1 and simm13
+ class F3_rs1simm13 : F3_rs1 {
+ bits<13> simm13;
+ set Inst{12-0} = simm13;
+ }
+
+
+ // Specific F3 classes...
+ //
+
+ class F3_1 opVal, bits<6> op3val, string name> : F3_rdrs1rs2 {
+ set op = opVal;
+ set op3 = op3val;
+ set Name = name;
+ set Inst{13} = 0; // i field = 0
+ //set Inst{12-5} = dontcare;
+ }
+
+ class F3_2 opVal, bits<6> op3val, string name> : F3_rdsimm13rs1 {
+ set op = opVal;
+ set op3 = op3val;
+ set Name = name;
+ set Inst{13} = 1; // i field = 1
+ }
+
+ class F3_3 opVal, bits<6> op3val, string name> : F3_rs1rs2 {
+ set op = opVal;
+ set op3 = op3val;
+ set Name = name;
+ set Inst{13} = 0;
+ }
+
+ class F3_4 opVal, bits<6> op3Val, string name> : F3_rs1simm13 {
+ bits<13> simm;
+ set op = opVal;
+ set op3 = op3Val;
+ set Name = name;
+ //set Inst{29-25} = dontcare;
+ set Inst{13} = 1;
+ set Inst{12-0} = simm;
+ }
+
+ class F3_11 opVal, bits<6> op3Val, string name> : F3_rdrs1rs2 {
+ bit x;
+ set op = opVal;
+ set op3 = op3Val;
+ set Name = name;
+ set Inst{13} = 0; // i field = 0
+ set Inst{12} = x;
+ //set Inst{11-5} = dontcare;
+ }
+
+ class F3_12 opVal, bits<6> op3Val, string name> : F3 {
+ bits<5> shcnt;
+
+ set Name = name;
+ set Inst{13} = 1; // i field = 1
+ set Inst{12} = 0; // x field = 0
+ //set Inst{11-5} = dontcare;
+ set Inst{4-0} = shcnt;
+ }
+
+ class F3_13 opVal, bits<6> op3Val, string name> : F3 {
+ bits<6> shcnt;
+
+ set Name = name;
+ set Inst{13} = 1; // i field = 1
+ set Inst{12} = 1; // x field = 1
+ //set Inst{11-6} = dontcare;
+ set Inst{5-0} = shcnt;
+ }
+
+ class F3_14 opVal, bits<6> op3Val,
+ bits<9> opfval, string name> : F3_rdrs1rs2 {
+ set op = opVal;
+ set op3 = op3Val;
+ set Name = name;
+ //set Inst{18-14} = dontcare;
+ set Inst{13-5} = opfval;
+ }
+
+ class F3_16 opVal, bits<6> op3Val,
+ bits<9> opfval, string name> : F3_rdrs1rs2 {
+ set op = opVal;
+ set op3 = op3Val;
+ set Name = name;
+ set Inst{13-5} = opfval;
+ }
+
+ class F3_17 opVal, bits<6> op3Val, string name> : F3_rdrs1 {
+ set op = opVal;
+ set op3 = op3Val;
+ set Name = name;
+ //Inst{13-0} = dontcare;
+ }
+
+ class F3_18 fcn, string name> : F3 {
+ set op = 2;
+ set op3 = 0b111110;
+ set Name = name;
+ set Inst{29-25} = fcn;
+ //set Inst{18-0 } = dontcare;
+ }
+
+ class F3_19 opVal, bits<6> op3Val, string name> : F3_rd {
+ set op = opVal;
+ set op3 = op3Val;
+ set Name = name;
+ //Inst{18-0} = dontcare;
+ }
+
+ // FIXME: class F3_20
+ // FIXME: class F3_21
Index: llvm/lib/Target/Sparc/SparcV9_F4.td
diff -c /dev/null llvm/lib/Target/Sparc/SparcV9_F4.td:1.1
*** /dev/null Wed May 28 22:31:53 2003
--- llvm/lib/Target/Sparc/SparcV9_F4.td Wed May 28 22:31:43 2003
***************
*** 0 ****
--- 1,90 ----
+ //===- Sparc.td - Target Description for Sparc V9 Target --------*- C++ -*-===//
+ // vim:ft=cpp
+ //===----------------------------------------------------------------------===//
+
+ //----------------------- F4 classes -----------------------------------------
+
+ // F4 - Common superclass of all F4 instructions. All instructions have an op3
+ // field.
+ class F4 : InstV9 {
+ bits<6> op3;
+ set Inst{24-19} = op3;
+ }
+
+ class F4_rd : F4 {
+ bits<5> rd;
+ set Inst{29-25} = rd;
+ }
+
+ class F4_rdsimm11 : F4_rd {
+ bits<11> simm11;
+ set Inst{10-0} = simm11;
+ }
+
+ class F4_rdsimm11rs1 : F4_rdsimm11 {
+ bits<5> rs1;
+ set Inst{18-14} = rs1;
+ }
+
+ // F4_rdrs1 - Common superclass of instructions that use rd & rs1
+ class F4_rdrs1 : F4_rd {
+ bits<5> rs1;
+ set Inst{18-14} = rs1;
+ }
+
+ // F4_rs1rdrs2 - Common superclass of instructions with rd, rs1, & rs2 fields
+ class F4_rdrs1rs2 : F4_rdrs1 {
+ bits<5> rs2;
+ set Inst{4-0} = rs2;
+ }
+
+ // F4_rs1 - Common class of instructions that do not have an rd field,
+ // but start at rs1
+ class F4_rs1 : F4 {
+ bits<5> rs1;
+ //set Inst{29-25} = dontcare;
+ set Inst{18-14} = rs1;
+ }
+
+ // F4_rs1rs2 - Common class of instructions that only have rs1 and rs2 fields
+ class F4_rs1rs2 : F4_rs1 {
+ bits<5> rs2;
+ //set Inst{12-5} = dontcare;
+ set Inst{4-0} = rs2;
+ }
+
+ // Actual F4 instruction classes
+
+ class F4_1 opVal, bits<6> op3Val, string name> : F4_rdrs1rs2 {
+ bits<2> cc;
+
+ set op = opVal;
+ set op3 = op3Val;
+ set Name = name;
+ set Inst{13} = 0; // i bit
+ set Inst{12-11} = cc;
+ //set Inst{10-5} = dontcare;
+ }
+
+ class F4_2 opVal, bits<6> op3Val, string name> : F4_rdsimm11rs1 {
+ bits<2> cc;
+
+ set op = opVal;
+ set op3 = op3Val;
+ set Name = name;
+ set Inst{13} = 1; // i bit
+ set Inst{12-11} = cc;
+ }
+
+ class F4_3 opVal, bits<6> op3Val, string name> : F3_rd {
+ bits<5> rs2;
+ bits<2> cc;
+
+ set op = opVal;
+ set op3 = op3Val;
+ set Name = name;
+ set Inst{13} = 0; // i bit
+ set Inst{12-11} = cc;
+ //set Inst{10-5} = dontcare;
+ set Inst{4-0} = rs2;
+ }
Index: llvm/lib/Target/Sparc/SparcV9_Reg.td
diff -c /dev/null llvm/lib/Target/Sparc/SparcV9_Reg.td:1.1
*** /dev/null Wed May 28 22:31:53 2003
--- llvm/lib/Target/Sparc/SparcV9_Reg.td Wed May 28 22:31:43 2003
***************
*** 0 ****
--- 1,23 ----
+ //===- Sparc.td - Target Description for Sparc V9 Target --------*- C++ -*-===//
+ // vim:ft=cpp
+ //===----------------------------------------------------------------------===//
+
+ //===----------------------------------------------------------------------===//
+ // Declarations that describe the Sparc register file
+ //===----------------------------------------------------------------------===//
+
+ class V9Reg : Register { set Namespace = "SparcV9"; }
+
+ // Ri - One of the 32 64 bit integer registers
+ class Ri num> : V9Reg { set Size = 64; field bits<5> Num = num; }
+
+ def G0 : Ri< 0>; def G1 : Ri< 1>; def G2 : Ri< 2>; def G3 : Ri< 3>;
+ def G4 : Ri< 4>; def G5 : Ri< 5>; def G6 : Ri< 6>; def G7 : Ri< 7>;
+ def O0 : Ri< 8>; def O1 : Ri< 9>; def O2 : Ri<10>; def O3 : Ri<11>;
+ def O4 : Ri<12>; def O5 : Ri<13>; def O6 : Ri<14>; def O7 : Ri<15>;
+ def L0 : Ri<16>; def L1 : Ri<17>; def L2 : Ri<18>; def L3 : Ri<19>;
+ def L4 : Ri<20>; def L5 : Ri<21>; def L6 : Ri<22>; def L7 : Ri<23>;
+ def I0 : Ri<24>; def I1 : Ri<25>; def I2 : Ri<26>; def I3 : Ri<27>;
+ def I4 : Ri<28>; def I5 : Ri<29>; def I6 : Ri<30>; def I7 : Ri<31>;
+ // Floating-point registers?
+ // ...
Index: llvm/lib/Target/Sparc/SparcV9.td
diff -u llvm/lib/Target/Sparc/SparcV9.td:1.3 llvm/lib/Target/Sparc/SparcV9.td:1.4
--- llvm/lib/Target/Sparc/SparcV9.td:1.3 Wed May 28 12:49:29 2003
+++ llvm/lib/Target/Sparc/SparcV9.td Wed May 28 22:31:43 2003
@@ -2,53 +2,12 @@
// vim:ft=cpp
//===----------------------------------------------------------------------===//
-//===----------------------------------------------------------------------===//
-// Target-Independent interface
-//===----------------------------------------------------------------------===//
-
-class Register {
- string Namespace = "";
- int Size;
-}
-
-class Instruction {
- string Name; // The opcode string for this instruction
- string Namespace = "";
-
- list Uses = []; // Default to using no non-operand registers
- list Defs = []; // Default to modifying no non-operand registers
-
- // These bits capture information about the high-level semantics of the
- // instruction.
- bit isReturn = 0; // Is this instruction a return instruction?
- bit isBranch = 0; // Is this instruction a branch instruction?
- bit isCall = 0; // Is this instruction a call instruction?
-}
+#include "../Target.td"
+#include "SparcV9_Reg.td"
//===----------------------------------------------------------------------===//
-// Declarations that describe the Sparc register file
-//===----------------------------------------------------------------------===//
-
-class V9Reg : Register { set Namespace = "SparcV9"; }
-
-// Ri - One of the 32 64 bit integer registers
-class Ri num> : V9Reg { set Size = 64; field bits<5> Num = num; }
-
-def G0 : Ri< 0>; def G1 : Ri< 1>; def G2 : Ri< 2>; def G3 : Ri< 3>;
-def G4 : Ri< 4>; def G5 : Ri< 5>; def G6 : Ri< 6>; def G7 : Ri< 7>;
-def O0 : Ri< 8>; def O1 : Ri< 9>; def O2 : Ri<10>; def O3 : Ri<11>;
-def O4 : Ri<12>; def O5 : Ri<13>; def O6 : Ri<14>; def O7 : Ri<15>;
-def L0 : Ri<16>; def L1 : Ri<17>; def L2 : Ri<18>; def L3 : Ri<19>;
-def L4 : Ri<20>; def L5 : Ri<21>; def L6 : Ri<22>; def L7 : Ri<23>;
-def I0 : Ri<24>; def I1 : Ri<25>; def I2 : Ri<26>; def I3 : Ri<27>;
-def I4 : Ri<28>; def I5 : Ri<29>; def I6 : Ri<30>; def I7 : Ri<31>;
-// Floating-point registers?
-// ...
-
-
-//===----------------------------------------------------------------------===//
-// This is temporary testing stuff.....
+// Instructions
//===----------------------------------------------------------------------===//
class InstV9 : Instruction { // Sparc instruction baseline
@@ -65,219 +24,9 @@
bit isPrivileged = 0; // Is this a privileged instruction?
}
-
-//===----------------------------------------------------------------------===//
-// Format #2 classes
-//
-class F2 : InstV9 { // Format 2 instructions
- bits<3> op2;
- set op = 0; // Op = 0
- set Inst{24-22} = op2;
-}
-
-// Format 2.1 instructions
-class F2_1 : F2 {
- bits<5> rd;
- bits<22> imm;
-
- set Name = name;
- set Inst{29-25} = rd;
- set Inst{21-0} = imm;
-}
-
-class F2_br : F2 { // Format 2 Branch instruction
- bit annul; // All branches have an annul bit
- set Inst{29} = annul;
- set isBranch = 1; // All instances are branch instructions
-}
-
-class F2_2 cond, string name> : F2_br { // Format 2.2 instructions
- bits<22> disp;
-
- set Name = name;
- set Inst{28-25} = cond;
- set Inst{21-0} = disp;
-}
-
-class F2_3 cond, string name> : F2_br { // Format 2.3 instructions
- bits<2> cc;
- bits<19> disp;
- bit predict;
-
- set Name = name;
- set Inst{28-25} = cond;
- set Inst{21-20} = cc;
- set Inst{19} = predict;
- set Inst{18-0} = disp;
-}
-
-class F2_4 rcond, string name> : F2_br { // Format 2.4 instructions
- // Variables exposed by the instruction...
- bit predict;
- bits<5> rs1;
- bits<16> disp;
-
- set Name = name;
- set Inst{28} = 0;
- set Inst{27-25} = rcond;
- // Inst{24-22} = op2 field
- set Inst{21-20} = disp{15-14};
- set Inst{19} = predict;
- set Inst{18-14} = rs1;
- set Inst{13-0 } = disp{13-0};
-}
-
-
-//===----------------------------------------------------------------------===//
-// Format #3 classes
-//
-
-// F3 - Common superclass of all F3 instructions. All instructions have an op3
-// field.
-class F3 : InstV9 {
- bits<6> op3;
- set op{1} = 1; // Op = 2 or 3
- set Inst{24-19} = op3;
-}
-
-class F3_rd : F3 {
- bits<5> rd;
- set Inst{29-25} = rd;
-}
-
-class F3_rdsimm13 : F3_rd {
- bits<13> simm13;
- set Inst{12-0} = simm13;
-}
-
-class F3_rdsimm13rs1 : F3_rdsimm13 {
- bits<5> rs1;
- set Inst{18-14} = rs1;
-}
-
-// F3_rdrs1 - Common superclass of instructions that use rd & rs1
-class F3_rdrs1 : F3_rd {
- bits<5> rs1;
- set Inst{18-14} = rs1;
-}
-
-// F3_rs1rdrs2 - Common superclass of instructions with rd, rs1, & rs2 fields
-class F3_rdrs1rs2 : F3_rdrs1 {
- bits<5> rs2;
- set Inst{4-0} = rs2;
-}
-
-// F3_rs1 - Common class of instructions that do not have an rd field,
-// but start at rs1
-class F3_rs1 : F3 {
- bits<5> rs1;
- //set Inst{29-25} = dontcare;
- set Inst{18-14} = rs1;
-}
-
-// F3_rs1rs2 - Common class of instructions that only have rs1 and rs2 fields
-class F3_rs1rs2 : F3_rs1 {
- bits<5> rs2;
- //set Inst{12-5} = dontcare;
- set Inst{4-0} = rs2;
-}
-
-// F3_rs1rs2 - Common class of instructions that only have rs1 and rs2 fields
-class F3_rs1simm13 : F3_rs1 {
- bits<13> simm13;
- set Inst{12-0} = simm13;
-}
-
-
-// Specific F3 classes...
-//
-
-class F3_1 opVal, bits<6> op3val, string name> : F3_rdrs1rs2 {
- set op = opVal;
- set op3 = op3val;
- set Name = name;
- set Inst{13} = 0; // i field = 0
- //set Inst{12-5} = dontcare;
-}
-
-class F3_2 opVal, bits<6> op3val, string name> : F3_rdsimm13rs1 {
- set op = opVal;
- set op3 = op3val;
- set Name = name;
- set Inst{13} = 1; // i field = 1
-}
-
-class F3_3 opVal, bits<6> op3val, string name> : F3_rs1rs2 {
- set op = opVal;
- set op3 = op3val;
- set Name = name;
- set Inst{13} = 0;
-}
-
-class F3_4 opVal, bits<6> op3Val, string name> : F3_rs1simm13 {
- bits<13> simm;
- set op = opVal;
- set op3 = op3Val;
- set Name = name;
- //set Inst{29-25} = dontcare;
- set Inst{13} = 1;
- set Inst{12-0} = simm;
-}
-
-class F3_11 opVal, bits<6> op3Val, string name> : F3_rdrs1rs2 {
- bit x;
- set op = opVal;
- set op3 = op3Val;
- set Name = name;
- set Inst{13} = 0; // i field = 0
- set Inst{12} = x;
- //set Inst{11-5} = dontcare;
-}
-
-class F3_12 opVal, bits<6> op3Val, string name> : F3 {
- bits<5> shcnt;
-
- set Name = name;
- set Inst{13} = 1; // i field = 1
- set Inst{12} = 0; // x field = 0
- //set Inst{11-5} = dontcare;
- set Inst{4-0} = shcnt;
-}
-
-class F3_13 opVal, bits<6> op3Val, string name> : F3 {
- bits<6> shcnt;
-
- set Name = name;
- set Inst{13} = 1; // i field = 1
- set Inst{12} = 1; // x field = 1
- //set Inst{11-6} = dontcare;
- set Inst{5-0} = shcnt;
-}
-
-class F3_14 opVal, bits<6> op3val,
- bits<9> opfval, string name> : F3_rdrs1rs2 {
- set op = opVal;
- set op3 = op3val;
- set Name = name;
- //set Inst{18-14} = dontcare;
- set Inst{13-5} = opfval;
-}
-
-class F3_16 opVal, bits<6> op3val,
- bits<9> opfval, string name> : F3_rdrs1rs2 {
- set op = opVal;
- set op3 = op3val;
- set Name = name;
- set Inst{13-5} = opfval;
-}
-
-class F3_18 fcn, string name> : F3 {
- set op = 2;
- set op3 = 0b111110;
- set Name = name;
- set Inst{29-25} = fcn;
- //set Inst{18-0 } = dontcare;
-}
+#include "SparcV9_F2.td"
+#include "SparcV9_F3.td"
+#include "SparcV9_F4.td"
//===----------------------------------------------------------------------===//
// Instruction list...
@@ -570,6 +319,12 @@
def FMOVFO : F4_7<2, 0b110101, 0b1111, "fmovfo">; // fmovfo r, r
#endif
+// Section A.34: Move F-P Register on Integer Register (FMOVr)
+
+// Section A.35: Move Integer Register on Condition (MOVcc)
+
+// Section A.36: Move Integer Register on Register Condition (MOVR)
+
// Section A.37: Multiply and Divide (64-bit) - p199
def MULXr : F3_1<2, 0b001001, "mulx">; // mulx r, r, r
def SDIVXr : F3_1<2, 0b101101, "sdivx">; // mulx r, r, r
@@ -593,6 +348,8 @@
// def SMULCCi : F3_1<2, 0b011011, "smulcc">; // smulcc r, i, r
//}
+// Section A.39: FIXME
+
// Section A.40: No operation - p204
// NOP is really a pseudo-instruction (special case of SETHI)
set op2 = 0b100 in {
@@ -603,6 +360,16 @@
}
}
+// Section A.41: FIXME
+// Section A.42: FIXME
+// Section A.43: FIXME
+
+// Section A.44: Read State Register
+// The only instr from this section currently used is RDCCR
+set rs1 = 2 in {
+ def RDCCR : F3_17<2, 0b101000, "rd">; // rd %ccr, r
+}
+
// Section A.45: RETURN - p216
set isReturn = 1 in {
def RETURNr : F3_3<2, 0b111001, "return">; // return
@@ -616,7 +383,7 @@
def RESTOREi : F3_2<2, 0b111101, "restore">; // restore r, i, r
// Section A.47: SAVED and RESTORED - p219
-// FIXME: add these instrs
+// Not currently used in Sparc backend
// Section A.48: SETHI - p220
set op2 = 0b100 in {
@@ -657,6 +424,9 @@
def SRLXi6 : F3_13<2, 0b100110, "srlx">; // srlx r, shcnt64, r
def SRAXi6 : F3_13<2, 0b100111, "srax">; // srax r, shcnt64, r
+// Section A.50: FIXME
+// Section A.51: FIXME
+
// Section A.52: Store Floating-point -p225
def STFr : F3_1<3, 0b100100, "st">; // st r, [r+r]
def STFi : F3_2<3, 0b100100, "st">; // st r, [r+i]
@@ -672,6 +442,8 @@
def STXFSRr : F3_1<3, 0b100101, "stq">; // stx r, [r+r]
def STXFSRi : F3_2<3, 0b100101, "stq">; // stx r, [r+i]
+// Section A.53: FIXME
+
// Section A.54: Store Integer - p229
def STBr : F3_1<3, 0b000101, "stb">; // stb r, [r+r]
def STBi : F3_2<3, 0b000101, "stb">; // stb r, [r+i]
@@ -683,6 +455,7 @@
def STXi : F3_2<3, 0b001110, "stb">; // stb r, [r+i]
// Floating point store...
+// Section A.55: FIXME
// Section A.56: Subtract - p233
def SUBr : F3_1<2, 0b000100, "sub">; // sub r, r, r
@@ -693,3 +466,5 @@
def SUBCi : F3_1<2, 0b001100, "subc">; // subc r, i, r
def SUBCccr : F3_1<2, 0b011100, "subccc">; // subccc r, r, r
def SUBCcci : F3_1<2, 0b011100, "subccc">; // subccc r, i, r
+
+// FIXME: More...?
From brukman at cs.uiuc.edu Wed May 28 22:33:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Wed May 28 22:33:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/Makefile
Message-ID: <200305290332.WAA23043@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
Makefile updated: 1.16 -> 1.17
---
Log message:
This should work better with re-generating the SparcV9CodeEmitter.inc file.
Also, added a rule to delete the generated .inc file on `make clean'.
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/Makefile
diff -u llvm/lib/Target/Sparc/Makefile:1.16 llvm/lib/Target/Sparc/Makefile:1.17
--- llvm/lib/Target/Sparc/Makefile:1.16 Wed May 28 12:41:09 2003
+++ llvm/lib/Target/Sparc/Makefile Wed May 28 22:32:49 2003
@@ -3,12 +3,6 @@
ExtraSource = Debug/Sparc.burm.cpp
-SparcV9CodeEmitter.cpp: SparcV9CodeEmitter.inc
-
-SparcV9CodeEmitter.inc: SparcV9.td
- @echo "TableGen-erating $@"
- cpp -P SparcV9.td | tblgen -gen-emitter > SparcV9CodeEmitter.inc
-
include $(LEVEL)/Makefile.common
ifdef ENABLE_OPTIMIZED
@@ -38,3 +32,11 @@
$(BUILD_ROOT)/Depend/Sparc.burm.d: $(BUILD_ROOT)/Depend/.dir
touch $@
+SparcV9CodeEmitter.cpp: SparcV9CodeEmitter.inc
+
+SparcV9CodeEmitter.inc: SparcV9.td
+ @echo "TableGen-erating $@"
+ cpp -P SparcV9.td | tblgen -gen-emitter > SparcV9CodeEmitter.inc
+
+clean::
+ rm -f SparcV9CodeEmitter.inc
From brukman at cs.uiuc.edu Wed May 28 23:55:00 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Wed May 28 23:55:00 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcV9.td
Message-ID: <200305290454.XAA23864@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
SparcV9.td updated: 1.4 -> 1.5
---
Log message:
Fixed to use the correct format of the instruction.
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/SparcV9.td
diff -u llvm/lib/Target/Sparc/SparcV9.td:1.4 llvm/lib/Target/Sparc/SparcV9.td:1.5
--- llvm/lib/Target/Sparc/SparcV9.td:1.4 Wed May 28 22:31:43 2003
+++ llvm/lib/Target/Sparc/SparcV9.td Wed May 28 23:53:56 2003
@@ -205,9 +205,9 @@
// Section A.24: Jump and Link
// Mimicking the Sparc's instr def...
def JMPLCALLr : F3_1<2, 0b111000, "jmpl">; // jmpl [r+r], r
-def JMPLCALLi : F3_1<2, 0b111000, "jmpl">; // jmpl [r+i], r
-def JMPLRETr : F3_1<2, 0b111000, "jmpl">; // jmpl [r+r], r
-def JMPLRETi : F3_1<2, 0b111000, "jmpl">; // jmpl [r+i], r
+def JMPLCALLi : F3_2<2, 0b111000, "jmpl">; // jmpl [r+i], r
+def JMPLRETr : F3_1<2, 0b111000, "jmpl">; // jmpl [r+r], r
+def JMPLRETi : F3_2<2, 0b111000, "jmpl">; // jmpl [r+i], r
// FIXME: FCMPS, FCMPD, FCMPQ !!!
// FIXME: FMULS, FMULD, FMULQ, ...
From brukman at cs.uiuc.edu Thu May 29 00:01:01 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Thu May 29 00:01:01 2003
Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetRegInfo.h
Message-ID: <200305290500.AAA23921@zion.cs.uiuc.edu>
Changes in directory llvm/include/llvm/Target:
TargetRegInfo.h updated: 1.34 -> 1.35
---
Log message:
Fixed misspelling and broke a line that was wrapping.
---
Diffs of the changes:
Index: llvm/include/llvm/Target/TargetRegInfo.h
diff -u llvm/include/llvm/Target/TargetRegInfo.h:1.34 llvm/include/llvm/Target/TargetRegInfo.h:1.35
--- llvm/include/llvm/Target/TargetRegInfo.h:1.34 Mon May 26 19:07:13 2003
+++ llvm/include/llvm/Target/TargetRegInfo.h Thu May 29 00:00:14 2003
@@ -178,7 +178,7 @@
// a regId in a register class to a common Id, or vice versa,
// we use the folloing two methods.
//
- // Thsi method converts from class reg. number to unified register number.
+ // This method converts from class reg. number to unified register number.
int getUnifiedRegNum(unsigned regClassID, int reg) const {
if (reg == getInvalidRegNum()) { return getInvalidRegNum(); }
assert(regClassID < getNumOfRegClasses() && "Invalid register class");
@@ -195,7 +195,8 @@
int totalRegs = 0, rcid = 0, NC = getNumOfRegClasses();
while (rcid < NC &&
- uRegNum >= totalRegs + (int) MachineRegClassArr[rcid]->getNumOfAllRegs()) {
+ uRegNum>= totalRegs+(int)MachineRegClassArr[rcid]->getNumOfAllRegs())
+ {
totalRegs += MachineRegClassArr[rcid]->getNumOfAllRegs();
rcid++;
}
From brukman at cs.uiuc.edu Thu May 29 00:30:03 2003
From: brukman at cs.uiuc.edu (Misha Brukman)
Date: Thu May 29 00:30:03 2003
Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/Makefile
Message-ID: <200305290529.AAA24180@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Target/Sparc:
Makefile updated: 1.17 -> 1.18
---
Log message:
When TableGen finds an error in the SparcV9.td file, it exits with a non-zero
exit code. This, in turn, makes an empty file SparcV9CodeEmitter.inc, and only
much later, produces a link error because the key function that TableGen creates
isn't found.
Using a temporary file in the middle forces a good .INC file to be generated by
TableGen, and it will keep trying until you fix the input file.
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/Makefile
diff -u llvm/lib/Target/Sparc/Makefile:1.17 llvm/lib/Target/Sparc/Makefile:1.18
--- llvm/lib/Target/Sparc/Makefile:1.17 Wed May 28 22:32:49 2003
+++ llvm/lib/Target/Sparc/Makefile Thu May 29 00:29:22 2003
@@ -34,9 +34,12 @@
SparcV9CodeEmitter.cpp: SparcV9CodeEmitter.inc
+TEMP_EMITTER_INC = _temp_emitter.inc
+
SparcV9CodeEmitter.inc: SparcV9.td
@echo "TableGen-erating $@"
- cpp -P SparcV9.td | tblgen -gen-emitter > SparcV9CodeEmitter.inc
+ cpp -P SparcV9.td | tblgen -gen-emitter > $(TEMP_EMITTER_INC)
+ mv -f $(TEMP_EMITTER_INC) SparcV9CodeEmitter.inc
clean::
rm -f SparcV9CodeEmitter.inc
From lattner at cs.uiuc.edu Thu May 29 10:07:02 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Thu May 29 10:07:02 2003
Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/Utils/Cloning.h
Message-ID: <200305291506.KAA15214@apoc.cs.uiuc.edu>
Changes in directory llvm/include/llvm/Transforms/Utils:
Cloning.h updated: 1.5 -> 1.6
---
Log message:
Doxygenify comments
---
Diffs of the changes:
Index: llvm/include/llvm/Transforms/Utils/Cloning.h
diff -u llvm/include/llvm/Transforms/Utils/Cloning.h:1.5 llvm/include/llvm/Transforms/Utils/Cloning.h:1.6
--- llvm/include/llvm/Transforms/Utils/Cloning.h:1.5 Thu Apr 17 22:49:22 2003
+++ llvm/include/llvm/Transforms/Utils/Cloning.h Thu May 29 10:06:40 2003
@@ -68,28 +68,27 @@
return CloneFunction(F, ValueMap);
}
-// Clone OldFunc into NewFunc, transforming the old arguments into references to
-// ArgMap values. Note that if NewFunc already has basic blocks, the ones
-// cloned into it will be added to the end of the function. This function fills
-// in a list of return instructions, and can optionally append the specified
-// suffix to all values cloned.
-//
+/// Clone OldFunc into NewFunc, transforming the old arguments into references
+/// to ArgMap values. Note that if NewFunc already has basic blocks, the ones
+/// cloned into it will be added to the end of the function. This function
+/// fills in a list of return instructions, and can optionally append the
+/// specified suffix to all values cloned.
+///
void CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
std::map &ValueMap,
std::vector &Returns,
const char *NameSuffix = "");
-// InlineFunction - This function forcibly inlines the called function into the
-// basic block of the caller. This returns true if it is not possible to inline
-// this call. The program is still in a well defined state if this occurs
-// though.
-//
-// Note that this only does one level of inlining. For example, if the
-// instruction 'call B' is inlined, and 'B' calls 'C', then the call to 'C' now
-// exists in the instruction stream. Similiarly this will inline a recursive
-// function by one level.
-//
+/// InlineFunction - This function inlines the called function into the basic
+/// block of the caller. This returns true if it is not possible to inline this
+/// call. The program is still in a well defined state if this occurs though.
+///
+/// Note that this only does one level of inlining. For example, if the
+/// instruction 'call B' is inlined, and 'B' calls 'C', then the call to 'C' now
+/// exists in the instruction stream. Similiarly this will inline a recursive
+/// function by one level.
+///
bool InlineFunction(CallInst *C);
#endif
From lattner at cs.uiuc.edu Thu May 29 10:08:04 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Thu May 29 10:08:04 2003
Subject: [llvm-commits] CVS: llvm/include/Support/Casting.h
Message-ID: <200305291507.KAA15272@apoc.cs.uiuc.edu>
Changes in directory llvm/include/Support:
Casting.h updated: 1.4 -> 1.5
---
Log message:
dyn_cast_or_null should work just the same as dyn_cast does
---
Diffs of the changes:
Index: llvm/include/Support/Casting.h
diff -u llvm/include/Support/Casting.h:1.4 llvm/include/Support/Casting.h:1.5
--- llvm/include/Support/Casting.h:1.4 Wed Apr 23 11:17:28 2003
+++ llvm/include/Support/Casting.h Thu May 29 10:07:48 2003
@@ -207,7 +207,7 @@
// be used to test for a type as well as cast if successful. This should be
// used in the context of an if statement like this:
//
-// if (const Instruction *I = dyn_cast(myVal)) { ... }
+// if (const Instruction *I = dyn_cast(myVal)) { ... }
//
template
@@ -219,8 +219,8 @@
// value is accepted.
//
template
-inline typename cast_retty::ret_type dyn_cast_or_null(Y *Val) {
- return (Val && isa(Val)) ? cast(Val) : 0;
+inline typename cast_retty::ret_type dyn_cast_or_null(Y Val) {
+ return (Val && isa(Val)) ? cast(Val) : 0;
}
From lattner at cs.uiuc.edu Thu May 29 10:09:01 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Thu May 29 10:09:01 2003
Subject: [llvm-commits] CVS: llvm/include/llvm/User.h
Message-ID: <200305291508.KAA15323@apoc.cs.uiuc.edu>
Changes in directory llvm/include/llvm:
User.h updated: 1.16 -> 1.17
---
Log message:
Don't require the user to do something like isa(II->get()). The ->get
should be implicit.
---
Diffs of the changes:
Index: llvm/include/llvm/User.h
diff -u llvm/include/llvm/User.h:1.16 llvm/include/llvm/User.h:1.17
--- llvm/include/llvm/User.h:1.16 Tue Oct 1 18:41:17 2002
+++ llvm/include/llvm/User.h Thu May 29 10:08:33 2003
@@ -73,4 +73,24 @@
}
};
+template<> struct simplify_type {
+ typedef Value* SimpleType;
+
+ static SimpleType getSimplifiedValue(const User::op_iterator &Val) {
+ return (SimpleType)Val->get();
+ }
+};
+template<> struct simplify_type
+ : public simplify_type {};
+
+template<> struct simplify_type {
+ typedef Value* SimpleType;
+
+ static SimpleType getSimplifiedValue(const User::const_op_iterator &Val) {
+ return (SimpleType)Val->get();
+ }
+};
+template<> struct simplify_type
+ : public simplify_type {};
+
#endif
From lattner at cs.uiuc.edu Thu May 29 10:12:01 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Thu May 29 10:12:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/InlineFunction.cpp
Message-ID: <200305291511.KAA15380@apoc.cs.uiuc.edu>
Changes in directory llvm/lib/Transforms/Utils:
InlineFunction.cpp added (r1.1)
---
Log message:
* Separate all of the grunt work of inlining out into the Utils library.
* Make the function inliner _significantly_ smarter. :)
---
Diffs of the changes:
Index: llvm/lib/Transforms/Utils/InlineFunction.cpp
diff -c /dev/null llvm/lib/Transforms/Utils/InlineFunction.cpp:1.1
*** /dev/null Thu May 29 10:11:41 2003
--- llvm/lib/Transforms/Utils/InlineFunction.cpp Thu May 29 10:11:31 2003
***************
*** 0 ****
--- 1,164 ----
+ //===- InlineFunction.cpp - Code to perform function inlining -------------===//
+ //
+ // This file implements inlining of a function into a call site, resolving
+ // parameters and the return value as appropriate.
+ //
+ // FIXME: This pass should transform alloca instructions in the called function
+ // into malloc/free pairs! Or perhaps it should refuse to inline them!
+ //
+ //===----------------------------------------------------------------------===//
+
+ #include "llvm/Transforms/Utils/Cloning.h"
+ #include "llvm/Module.h"
+ #include "llvm/iTerminators.h"
+ #include "llvm/iPHINode.h"
+ #include "llvm/iMemory.h"
+ #include "llvm/iOther.h"
+ #include "llvm/DerivedTypes.h"
+
+ // InlineFunction - This function inlines the called function into the basic
+ // block of the caller. This returns false if it is not possible to inline this
+ // call. The program is still in a well defined state if this occurs though.
+ //
+ // Note that this only does one level of inlining. For example, if the
+ // instruction 'call B' is inlined, and 'B' calls 'C', then the call to 'C' now
+ // exists in the instruction stream. Similiarly this will inline a recursive
+ // function by one level.
+ //
+ bool InlineFunction(CallInst *CI) {
+ assert(isa(CI) && "InlineFunction only works on CallInst nodes");
+ assert(CI->getParent() && "Instruction not embedded in basic block!");
+ assert(CI->getParent()->getParent() && "Instruction not in function!");
+
+ const Function *CalledFunc = CI->getCalledFunction();
+ if (CalledFunc == 0 || // Can't inline external function or indirect
+ CalledFunc->isExternal() || // call, or call to a vararg function!
+ CalledFunc->getFunctionType()->isVarArg()) return false;
+
+ BasicBlock *OrigBB = CI->getParent();
+ Function *Caller = OrigBB->getParent();
+
+ // Call splitBasicBlock - The original basic block now ends at the instruction
+ // immediately before the call. The original basic block now ends with an
+ // unconditional branch to NewBB, and NewBB starts with the call instruction.
+ //
+ BasicBlock *NewBB = OrigBB->splitBasicBlock(CI);
+ NewBB->setName(OrigBB->getName()+".split");
+
+ // Remove (unlink) the CallInst from the start of the new basic block.
+ NewBB->getInstList().remove(CI);
+
+ // If we have a return value generated by this call, convert it into a PHI
+ // node that gets values from each of the old RET instructions in the original
+ // function.
+ //
+ PHINode *PHI = 0;
+ if (!CI->use_empty()) {
+ // The PHI node should go at the front of the new basic block to merge all
+ // possible incoming values.
+ //
+ PHI = new PHINode(CalledFunc->getReturnType(), CI->getName(),
+ NewBB->begin());
+
+ // Anything that used the result of the function call should now use the PHI
+ // node as their operand.
+ //
+ CI->replaceAllUsesWith(PHI);
+ }
+
+ // Get an iterator to the last basic block in the function, which will have
+ // the new function inlined after it.
+ //
+ Function::iterator LastBlock = &Caller->back();
+
+ // Calculate the vector of arguments to pass into the function cloner...
+ std::map ValueMap;
+ assert((unsigned)std::distance(CalledFunc->abegin(), CalledFunc->aend()) ==
+ CI->getNumOperands()-1 && "No varargs calls can be inlined yet!");
+
+ unsigned i = 1;
+ for (Function::const_aiterator I = CalledFunc->abegin(), E=CalledFunc->aend();
+ I != E; ++I, ++i)
+ ValueMap[I] = CI->getOperand(i);
+
+ // Since we are now done with the CallInst, we can delete it.
+ delete CI;
+
+ // Make a vector to capture the return instructions in the cloned function...
+ std::vector Returns;
+
+ // Populate the value map with all of the globals in the program.
+ Module &M = *Caller->getParent();
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
+ ValueMap[I] = I;
+ for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
+ ValueMap[I] = I;
+
+ // Do all of the hard part of cloning the callee into the caller...
+ CloneFunctionInto(Caller, CalledFunc, ValueMap, Returns, ".i");
+
+ // Loop over all of the return instructions, turning them into unconditional
+ // branches to the merge point now...
+ for (unsigned i = 0, e = Returns.size(); i != e; ++i) {
+ ReturnInst *RI = Returns[i];
+ BasicBlock *BB = RI->getParent();
+
+ // Add a branch to the merge point where the PHI node would live...
+ new BranchInst(NewBB, RI);
+
+ if (PHI) { // The PHI node should include this value!
+ assert(RI->getReturnValue() && "Ret should have value!");
+ assert(RI->getReturnValue()->getType() == PHI->getType() &&
+ "Ret value not consistent in function!");
+ PHI->addIncoming(RI->getReturnValue(), BB);
+ }
+
+ // Delete the return instruction now
+ BB->getInstList().erase(RI);
+ }
+
+ // Check to see if the PHI node only has one argument. This is a common
+ // case resulting from there only being a single return instruction in the
+ // function call. Because this is so common, eliminate the PHI node.
+ //
+ if (PHI && PHI->getNumIncomingValues() == 1) {
+ PHI->replaceAllUsesWith(PHI->getIncomingValue(0));
+ PHI->getParent()->getInstList().erase(PHI);
+ }
+
+ // Change the branch that used to go to NewBB to branch to the first basic
+ // block of the inlined function.
+ //
+ TerminatorInst *Br = OrigBB->getTerminator();
+ assert(Br && Br->getOpcode() == Instruction::Br &&
+ "splitBasicBlock broken!");
+ Br->setOperand(0, ++LastBlock);
+
+ // If there are any alloca instructions in the block that used to be the entry
+ // block for the callee, move them to the entry block of the caller. First
+ // calculate which instruction they should be inserted before. We insert the
+ // instructions at the end of the current alloca list.
+ //
+ BasicBlock::iterator InsertPoint = Caller->begin()->begin();
+ while (isa(InsertPoint)) ++InsertPoint;
+
+ for (BasicBlock::iterator I = LastBlock->begin(), E = LastBlock->end();
+ I != E; )
+ if (AllocaInst *AI = dyn_cast(I)) {
+ ++I; // Move to the next instruction
+ LastBlock->getInstList().remove(AI);
+ Caller->front().getInstList().insert(InsertPoint, AI);
+
+ } else {
+ ++I;
+ }
+
+ // Now that the function is correct, make it a little bit nicer. In
+ // particular, move the basic blocks inserted from the end of the function
+ // into the space made by splitting the source basic block.
+ //
+ Caller->getBasicBlockList().splice(NewBB, Caller->getBasicBlockList(),
+ LastBlock, Caller->end());
+
+ return true;
+ }
From lattner at cs.uiuc.edu Thu May 29 10:12:06 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Thu May 29 10:12:06 2003
Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/FunctionInlining.cpp
Message-ID: <200305291511.KAA15387@apoc.cs.uiuc.edu>
Changes in directory llvm/lib/Transforms/IPO:
FunctionInlining.cpp updated: 1.44 -> 1.45
---
Log message:
* Separate all of the grunt work of inlining out into the Utils library.
* Make the function inliner _significantly_ smarter. :)
---
Diffs of the changes:
Index: llvm/lib/Transforms/IPO/FunctionInlining.cpp
diff -u llvm/lib/Transforms/IPO/FunctionInlining.cpp:1.44 llvm/lib/Transforms/IPO/FunctionInlining.cpp:1.45
--- llvm/lib/Transforms/IPO/FunctionInlining.cpp:1.44 Wed May 7 21:36:43 2003
+++ llvm/lib/Transforms/IPO/FunctionInlining.cpp Thu May 29 10:11:31 2003
@@ -1,15 +1,6 @@
//===- FunctionInlining.cpp - Code to perform function inlining -----------===//
//
-// This file implements inlining of functions.
-//
-// Specifically, this:
-// * Exports functionality to inline any function call
-// * Inlines functions that consist of a single basic block
-// * Is able to inline ANY function call
-// . Has a smart heuristic for when to inline a function
-//
-// FIXME: This pass should transform alloca instructions in the called function
-// into malloc/free pairs! Or perhaps it should refuse to inline them!
+// This file implements bottom-up inlining of functions into callees.
//
//===----------------------------------------------------------------------===//
@@ -17,194 +8,161 @@
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
-#include "llvm/iTerminators.h"
-#include "llvm/iPHINode.h"
#include "llvm/iOther.h"
-#include "llvm/DerivedTypes.h"
+#include "llvm/iMemory.h"
#include "Support/Statistic.h"
-#include
+#include
-static Statistic<> NumInlined("inline", "Number of functions inlined");
+namespace {
+ Statistic<> NumInlined("inline", "Number of functions inlined");
-// InlineFunction - This function forcibly inlines the called function into the
-// basic block of the caller. This returns false if it is not possible to
-// inline this call. The program is still in a well defined state if this
-// occurs though.
-//
-// Note that this only does one level of inlining. For example, if the
-// instruction 'call B' is inlined, and 'B' calls 'C', then the call to 'C' now
-// exists in the instruction stream. Similiarly this will inline a recursive
-// function by one level.
-//
-bool InlineFunction(CallInst *CI) {
- assert(isa(CI) && "InlineFunction only works on CallInst nodes");
- assert(CI->getParent() && "Instruction not embedded in basic block!");
- assert(CI->getParent()->getParent() && "Instruction not in function!");
-
- const Function *CalledFunc = CI->getCalledFunction();
- if (CalledFunc == 0 || // Can't inline external function or indirect
- CalledFunc->isExternal() || // call, or call to a vararg function!
- CalledFunc->getFunctionType()->isVarArg()) return false;
-
- //std::cerr << "Inlining " << CalledFunc->getName() << " into "
- // << CurrentMeth->getName() << "\n";
-
- BasicBlock *OrigBB = CI->getParent();
-
- // Call splitBasicBlock - The original basic block now ends at the instruction
- // immediately before the call. The original basic block now ends with an
- // unconditional branch to NewBB, and NewBB starts with the call instruction.
- //
- BasicBlock *NewBB = OrigBB->splitBasicBlock(CI);
- NewBB->setName("InlinedFunctionReturnNode");
+ struct FunctionInlining : public Pass {
+ virtual bool run(Module &M) {
+ bool Changed = false;
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
+ Changed |= doInlining(I);
+ ProcessedFunctions.clear();
+ return Changed;
+ }
- // Remove (unlink) the CallInst from the start of the new basic block.
- NewBB->getInstList().remove(CI);
+ private:
+ std::set ProcessedFunctions; // Prevent infinite recursion
+ bool doInlining(Function *F);
+ };
+ RegisterOpt X("inline", "Function Integration/Inlining");
+}
- // If we have a return value generated by this call, convert it into a PHI
- // node that gets values from each of the old RET instructions in the original
- // function.
- //
- PHINode *PHI = 0;
- if (!CI->use_empty()) {
- // The PHI node should go at the front of the new basic block to merge all
- // possible incoming values.
- //
- PHI = new PHINode(CalledFunc->getReturnType(), CI->getName(),
- NewBB->begin());
+Pass *createFunctionInliningPass() { return new FunctionInlining(); }
- // Anything that used the result of the function call should now use the PHI
- // node as their operand.
- //
- CI->replaceAllUsesWith(PHI);
- }
- // Get a pointer to the last basic block in the function, which will have the
- // new function inlined after it.
- //
- Function::iterator LastBlock = &OrigBB->getParent()->back();
+// ShouldInlineFunction - The heuristic used to determine if we should inline
+// the function call or not.
+//
+static inline bool ShouldInlineFunction(const CallInst *CI) {
+ assert(CI->getParent() && CI->getParent()->getParent() &&
+ "Call not embedded into a function!");
- // Calculate the vector of arguments to pass into the function cloner...
- std::map ValueMap;
- assert((unsigned)std::distance(CalledFunc->abegin(), CalledFunc->aend()) ==
- CI->getNumOperands()-1 && "No varargs calls can be inlined yet!");
-
- unsigned i = 1;
- for (Function::const_aiterator I = CalledFunc->abegin(), E=CalledFunc->aend();
- I != E; ++I, ++i)
- ValueMap[I] = CI->getOperand(i);
-
- // Since we are now done with the CallInst, we can delete it.
- delete CI;
-
- // Make a vector to capture the return instructions in the cloned function...
- std::vector Returns;
-
- // Populate the value map with all of the globals in the program.
- Module &M = *OrigBB->getParent()->getParent();
- for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
- ValueMap[I] = I;
- for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
- ValueMap[I] = I;
-
- // Do all of the hard part of cloning the callee into the caller...
- CloneFunctionInto(OrigBB->getParent(), CalledFunc, ValueMap, Returns, ".i");
-
- // Loop over all of the return instructions, turning them into unconditional
- // branches to the merge point now...
- for (unsigned i = 0, e = Returns.size(); i != e; ++i) {
- ReturnInst *RI = Returns[i];
- BasicBlock *BB = RI->getParent();
-
- // Add a branch to the merge point where the PHI node would live...
- new BranchInst(NewBB, RI);
-
- if (PHI) { // The PHI node should include this value!
- assert(RI->getReturnValue() && "Ret should have value!");
- assert(RI->getReturnValue()->getType() == PHI->getType() &&
- "Ret value not consistent in function!");
- PHI->addIncoming(RI->getReturnValue(), BB);
- }
+ const Function *Callee = CI->getCalledFunction();
+ if (Callee == 0 || Callee->isExternal())
+ return false; // Cannot inline an indirect call... or external function.
- // Delete the return instruction now
- BB->getInstList().erase(RI);
- }
+ // Don't inline a recursive call.
+ const Function *Caller = CI->getParent()->getParent();
+ if (Caller == Callee) return false;
- // Check to see if the PHI node only has one argument. This is a common
- // case resulting from there only being a single return instruction in the
- // function call. Because this is so common, eliminate the PHI node.
+ // InlineQuality - This value measures how good of an inline candidate this
+ // call site is to inline. The initial value determines how aggressive the
+ // inliner is. If this value is negative after the final computation,
+ // inlining is not performed.
//
- if (PHI && PHI->getNumIncomingValues() == 1) {
- PHI->replaceAllUsesWith(PHI->getIncomingValue(0));
- PHI->getParent()->getInstList().erase(PHI);
- }
+ int InlineQuality = 200; // FIXME: This is VERY conservative
- // Change the branch that used to go to NewBB to branch to the first basic
- // block of the inlined function.
+ // If there is only one call of the function, and it has internal linkage,
+ // make it almost guaranteed to be inlined.
//
- TerminatorInst *Br = OrigBB->getTerminator();
- assert(Br && Br->getOpcode() == Instruction::Br &&
- "splitBasicBlock broken!");
- Br->setOperand(0, ++LastBlock);
- return true;
-}
+ if (Callee->use_size() == 1 && Callee->hasInternalLinkage())
+ InlineQuality += 30000;
-static inline bool ShouldInlineFunction(const CallInst *CI, const Function *F) {
- assert(CI->getParent() && CI->getParent()->getParent() &&
- "Call not embedded into a function!");
-
- // Don't inline a recursive call.
- if (CI->getParent()->getParent() == F) return false;
+ // Add to the inline quality for properties that make the call valueable to
+ // inline. This includes factors that indicate that the result of inlining
+ // the function will be optimizable. Currently this just looks at arguments
+ // passed into the function.
+ //
+ for (User::const_op_iterator I = CI->op_begin()+1, E = CI->op_end();
+ I != E; ++I){
+ // Each argument passed in has a cost at both the caller and the callee
+ // sides. This favors functions that take many arguments over functions
+ // that take few arguments.
+ InlineQuality += 20;
+
+ // If this is a function being passed in, it is very likely that we will be
+ // able to turn an indirect function call into a direct function call.
+ if (isa(I))
+ InlineQuality += 100;
+
+ // If a constant, global variable or alloca is passed in, inlining this
+ // function is likely to allow significant future optimization possibilities
+ // (constant propagation, scalar promotion, and scalarization), so encourage
+ // the inlining of the function.
+ //
+ else if (isa(I) || isa(I) || isa(I))
+ InlineQuality += 60;
+ }
- // Don't inline something too big. This is a really crappy heuristic
- if (F->size() > 3) return false;
+ // Now that we have considered all of the factors that make the call site more
+ // likely to be inlined, look at factors that make us not want to inline it.
+ // As soon as the inline quality gets negative, bail out.
+
+ // Look at the size of the callee. Each basic block counts as 20 units, and
+ // each instruction counts as 10.
+ for (Function::const_iterator BB = Callee->begin(), E = Callee->end();
+ BB != E; ++BB) {
+ InlineQuality -= BB->size()*10 + 20;
+ if (InlineQuality < 0) return false;
+ }
- // Don't inline into something too big. This is a **really** crappy heuristic
- if (CI->getParent()->getParent()->size() > 10) return false;
+ // Don't inline into something too big, which would make it bigger. Here, we
+ // count each basic block as a single unit.
+ for (Function::const_iterator BB = Caller->begin(), E = Caller->end();
+ BB != E; ++BB) {
+ --InlineQuality;
+ if (InlineQuality < 0) return false;
+ }
- // Go ahead and try just about anything else.
+ // If we get here, this call site is high enough "quality" to inline.
+ DEBUG(std::cerr << "Inlining in '" << Caller->getName()
+ << "', quality = " << InlineQuality << ": " << *CI);
return true;
}
-static inline bool DoFunctionInlining(BasicBlock *BB) {
- for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) {
- if (CallInst *CI = dyn_cast(I)) {
- // Check to see if we should inline this function
- Function *F = CI->getCalledFunction();
- if (F && ShouldInlineFunction(CI, F)) {
- return InlineFunction(CI);
- }
- }
- }
- return false;
-}
-
-// doFunctionInlining - Use a heuristic based approach to inline functions that
-// seem to look good.
+// doInlining - Use a heuristic based approach to inline functions that seem to
+// look good.
//
-static bool doFunctionInlining(Function &F) {
- bool Changed = false;
+bool FunctionInlining::doInlining(Function *F) {
+ // If we have already processed this function (ie, it is recursive) don't
+ // revisit.
+ std::set::iterator PFI = ProcessedFunctions.lower_bound(F);
+ if (PFI != ProcessedFunctions.end() && *PFI == F) return false;
+
+ // Insert the function in the set so it doesn't get revisited.
+ ProcessedFunctions.insert(PFI, F);
- // Loop through now and inline instructions a basic block at a time...
- for (Function::iterator I = F.begin(); I != F.end(); )
- if (DoFunctionInlining(I)) {
- ++NumInlined;
- Changed = true;
- } else {
- ++I;
+ bool Changed = false;
+ for (Function::iterator BB = F->begin(); BB != F->end(); ++BB)
+ for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ) {
+ bool ShouldInc = true;
+ // Found a call instruction? FIXME: This should also handle INVOKEs
+ if (CallInst *CI = dyn_cast(I)) {
+ if (Function *Callee = CI->getCalledFunction())
+ doInlining(Callee); // Inline in callees before callers!
+
+ // Decide whether we should inline this function...
+ if (ShouldInlineFunction(CI)) {
+ // Save an iterator to the instruction before the call if it exists,
+ // otherwise get an iterator at the end of the block... because the
+ // call will be destroyed.
+ //
+ BasicBlock::iterator SI;
+ if (I != BB->begin()) {
+ SI = I; --SI; // Instruction before the call...
+ } else {
+ SI = BB->end();
+ }
+
+ // Attempt to inline the function...
+ if (InlineFunction(CI)) {
+ ++NumInlined;
+ Changed = true;
+ // Move to instruction before the call...
+ I = (SI == BB->end()) ? BB->begin() : SI;
+ ShouldInc = false; // Don't increment iterator until next time
+ }
+ }
+ }
+ if (ShouldInc) ++I;
}
return Changed;
}
-namespace {
- struct FunctionInlining : public FunctionPass {
- virtual bool runOnFunction(Function &F) {
- return doFunctionInlining(F);
- }
- };
- RegisterOpt X("inline", "Function Integration/Inlining");
-}
-
-Pass *createFunctionInliningPass() { return new FunctionInlining(); }
From lattner at cs.uiuc.edu Thu May 29 10:13:01 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Thu May 29 10:13:01 2003
Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/DemoteRegToStack.cpp
Message-ID: <200305291512.KAA15453@apoc.cs.uiuc.edu>
Changes in directory llvm/lib/Transforms/Utils:
DemoteRegToStack.cpp updated: 1.1 -> 1.2
---
Log message:
Eliminate unnecessary ->get calls that are now automatically handled.
---
Diffs of the changes:
Index: llvm/lib/Transforms/Utils/DemoteRegToStack.cpp
diff -u llvm/lib/Transforms/Utils/DemoteRegToStack.cpp:1.1 llvm/lib/Transforms/Utils/DemoteRegToStack.cpp:1.2
--- llvm/lib/Transforms/Utils/DemoteRegToStack.cpp:1.1 Tue Dec 10 07:07:58 2002
+++ llvm/lib/Transforms/Utils/DemoteRegToStack.cpp Thu May 29 10:12:27 2003
@@ -1,14 +1,14 @@
//===- DemoteRegToStack.cpp - Move a virtual reg. to stack ------*- C++ -*-===//
//
-// This file provide the function DemoteRegToStack().
-// This function takes a virtual register computed by an
-// Instruction& X and replaces it with a slot in the stack frame,
-// allocated via alloca. It returns the pointer to the AllocaInst inserted.
+// This file provide the function DemoteRegToStack(). This function takes a
+// virtual register computed by an Instruction& X and replaces it with a slot in
+// the stack frame, allocated via alloca. It returns the pointer to the
+// AllocaInst inserted.
+//
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Utils/DemoteRegToStack.h"
#include "llvm/Function.h"
-#include "llvm/BasicBlock.h"
#include "llvm/iMemory.h"
#include "llvm/iPHINode.h"
#include "llvm/iTerminators.h"
@@ -16,7 +16,6 @@
#include "Support/hash_set"
#include
-
//----------------------------------------------------------------------------
// function DemoteRegToStack()
//
@@ -28,11 +27,10 @@
// Helper function to push a phi *and* all its operands to the worklist!
// Do not push an instruction if it is already in the result set of Phis to go.
inline void PushOperandsOnWorkList(std::stack& workList,
- PhiSet& phisToGo, PHINode* phiN)
-{
- for (User::op_iterator OI=phiN->op_begin(), OE=phiN->op_end();
+ PhiSet& phisToGo, PHINode* phiN) {
+ for (User::op_iterator OI = phiN->op_begin(), OE = phiN->op_end();
OI != OE; ++OI)
- if (Instruction* opI = dyn_cast(OI->get()))
+ if (Instruction* opI = dyn_cast(OI))
if (!isa(opI) ||
phisToGo.find(cast(opI)) == phisToGo.end())
workList.push(opI);
From lattner at cs.uiuc.edu Thu May 29 10:13:05 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Thu May 29 10:13:05 2003
Subject: [llvm-commits] CVS: llvm/lib/CWriter/Writer.cpp
Message-ID: <200305291512.KAA15432@apoc.cs.uiuc.edu>
Changes in directory llvm/lib/CWriter:
Writer.cpp updated: 1.88 -> 1.89
---
Log message:
Eliminate unnecessary ->get calls that are now automatically handled.
---
Diffs of the changes:
Index: llvm/lib/CWriter/Writer.cpp
diff -u llvm/lib/CWriter/Writer.cpp:1.88 llvm/lib/CWriter/Writer.cpp:1.89
--- llvm/lib/CWriter/Writer.cpp:1.88 Sat May 17 17:26:30 2003
+++ llvm/lib/CWriter/Writer.cpp Thu May 29 10:12:27 2003
@@ -694,7 +694,7 @@
E = STy->getElementTypes().end(); I != E; ++I) {
const Type *Ty1 = I->get();
if (isa(Ty1) || isa(Ty1))
- printContainedStructs(Ty1, StructPrinted);
+ printContainedStructs(*I, StructPrinted);
}
//Print structure type out..
@@ -1121,7 +1121,7 @@
return;
}
- const Constant *CI = dyn_cast(I->get());
+ const Constant *CI = dyn_cast(I);
if (HasImplicitAddress && (!CI || !CI->isNullValue()))
Out << "(&";
From lattner at cs.uiuc.edu Thu May 29 10:13:08 2003
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Thu May 29 10:13:08 2003
Subject: [llvm-commits] CVS: llvm/lib/Transforms/ExprTypeConvert.cpp
Message-ID: <200305291512.KAA15439@apoc.cs.uiuc.edu>
Changes in directory llvm/lib/Transforms:
ExprTypeConvert.cpp updated: 1.72 -> 1.73
---
Log message:
Eliminate unnecessary ->get calls that are now automatically handled.
---
Diffs of the changes:
Index: llvm/lib/Transforms/ExprTypeConvert.cpp
diff -u llvm/lib/Transforms/ExprTypeConvert.cpp:1.72 llvm/lib/Transforms/ExprTypeConvert.cpp:1.73
--- llvm/lib/Transforms/ExprTypeConvert.cpp:1.72 Tue May 20 16:01:14 2003
+++ llvm/lib/Transforms/ExprTypeConvert.cpp Thu May 29 10:12:27 2003
@@ -1257,7 +1257,7 @@
for (User::op_iterator OI = I->op_begin(), OE = I->op_end();
OI != OE; ++OI)
- if (Instruction *U = dyn_cast(OI->get())) {
+ if (Instruction *U = dyn_cast