[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp
Chris Lattner
lattner at cs.uiuc.edu
Mon Jan 10 19:11:57 PST 2005
Changes in directory llvm/lib/Target/X86:
X86ISelPattern.cpp updated: 1.22 -> 1.23
---
Log message:
Take register pressure into account when we have to decide whether to
evaluate the LHS or the RHS of an operation first. This causes good things
to happen. For example, instead of compiling a loop to this:
.LBBstrength_result7_1: # loopentry
movl 16(%esp), %edi
movl (%edi), %edi ;;; LOAD
movl (%ecx), %ebx
movl $2, (%eax,%ebx,4)
movl (%edx), %ebx
movl %esi, %ebp
addl $21, %ebp
addl $42, %esi
cmpl $0, %edi ;;; USE
cmovne %esi, %ebp
cmpl %ebp, %ebx
movl %ebp, %esi
jg .LBBstrength_result7_1
We now compile it to this:
.LBBstrength_result7_1: # loopentry
movl %edi, %ebx
addl $42, %ebx
addl $21, %edi
movl (%ecx), %ebp ;; LOAD
cmpl $0, %ebp ;; USE
cmovne %ebx, %edi
movl (%edx), %ebx
movl $2, (%eax,%ebx,4)
movl (%esi), %ebx
cmpl %edi, %ebx
jg .LBBstrength_result7_1
Which reduces register pressure enough (in this case) to avoid spilling in the
loop.
As another example, consider the CodeGen/X86/regpressure.ll testcase. We
used to generate this code for both cases:
regpressure1:
subl $32, %esp
movl %esi, 12(%esp)
movl %edi, 8(%esp)
movl %ebx, 4(%esp)
movl %ebp, (%esp)
movl 36(%esp), %ecx
movl (%ecx), %eax
movl 4(%ecx), %edx
movl %edx, 24(%esp)
movl 8(%ecx), %edx
movl %edx, 16(%esp)
movl 12(%ecx), %edx
movl 16(%ecx), %esi
movl 20(%ecx), %edi
movl 24(%ecx), %ebx
movl %ebx, 28(%esp)
movl 28(%ecx), %ebx
movl 32(%ecx), %ebp
movl %ebp, 20(%esp)
movl 36(%ecx), %ecx
imull 24(%esp), %eax
imull 16(%esp), %eax
imull %edx, %eax
imull %esi, %eax
imull %edi, %eax
imull 28(%esp), %eax
imull %ebx, %eax
imull 20(%esp), %eax
imull %ecx, %eax
movl (%esp), %ebp
movl 4(%esp), %ebx
movl 8(%esp), %edi
movl 12(%esp), %esi
addl $32, %esp
ret
This code is basically trying to do all of the loads first, then execute all
of the multiplies. Because we run out of registers, lots of spill code happens.
We now generate this code for both cases:
regpressure1:
movl 4(%esp), %ecx
movl (%ecx), %eax
movl 4(%ecx), %edx
imull %edx, %eax
movl 8(%ecx), %edx
imull %edx, %eax
movl 12(%ecx), %edx
imull %edx, %eax
movl 16(%ecx), %edx
imull %edx, %eax
movl 20(%ecx), %edx
imull %edx, %eax
movl 24(%ecx), %edx
imull %edx, %eax
movl 28(%ecx), %edx
imull %edx, %eax
movl 32(%ecx), %edx
imull %edx, %eax
movl 36(%ecx), %ecx
imull %ecx, %eax
ret
which is much nicer (when we fold loads into the muls it will be even better).
The old instruction selector used to produce the good code for regpressure1
but not for regpressure2, as it depended on the order of operations in the
LLVM code.
---
Diffs of the changes: (+232 -41)
Index: llvm/lib/Target/X86/X86ISelPattern.cpp
diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.22 llvm/lib/Target/X86/X86ISelPattern.cpp:1.23
--- llvm/lib/Target/X86/X86ISelPattern.cpp:1.22 Mon Jan 10 16:10:13 2005
+++ llvm/lib/Target/X86/X86ISelPattern.cpp Mon Jan 10 21:11:44 2005
@@ -303,6 +303,9 @@
/// X86-specific SelectionDAG.
X86TargetLowering X86Lowering;
+ /// RegPressureMap - This keeps an approximate count of the number of
+ /// registers required to evaluate each node in the graph.
+ std::map<SDNode*, unsigned> RegPressureMap;
/// ExprMap - As shared expressions are codegen'd, we keep track of which
/// vreg the value is produced in, so we only emit one copy of each compiled
@@ -314,6 +317,11 @@
ISel(TargetMachine &TM) : SelectionDAGISel(X86Lowering), X86Lowering(TM) {
}
+ unsigned getRegPressure(SDOperand O) {
+ return RegPressureMap[O.Val];
+ }
+ unsigned ComputeRegPressure(SDOperand O);
+
/// InstructionSelectBasicBlock - This callback is invoked by
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
@@ -321,6 +329,12 @@
// FP_REG_KILL insertion.
ContainsFPCode = false;
+ // Compute the RegPressureMap, which is an approximation for the number of
+ // registers required to compute each node.
+ ComputeRegPressure(DAG.getRoot());
+
+ //DAG.viewGraph();
+
// Codegen the basic block.
Select(DAG.getRoot());
@@ -344,6 +358,7 @@
// Clear state used for selection.
ExprMap.clear();
LoweredTokens.clear();
+ RegPressureMap.clear();
}
void EmitCMP(SDOperand LHS, SDOperand RHS);
@@ -356,6 +371,32 @@
};
}
+// ComputeRegPressure - Compute the RegPressureMap, which is an approximation
+// for the number of registers required to compute each node. This is basically
+// computing a generalized form of the Sethi-Ullman number for each node.
+unsigned ISel::ComputeRegPressure(SDOperand O) {
+ SDNode *N = O.Val;
+ unsigned &Result = RegPressureMap[N];
+ if (Result) return Result;
+
+ if (N->getNumOperands() == 0)
+ return Result = 1;
+
+ unsigned MaxRegUse = 0;
+ unsigned NumExtraMaxRegUsers = 0;
+ for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
+ unsigned Regs = ComputeRegPressure(N->getOperand(i));
+ if (Regs > MaxRegUse) {
+ MaxRegUse = Regs;
+ NumExtraMaxRegUsers = 0;
+ } else if (Regs == MaxRegUse) {
+ ++NumExtraMaxRegUsers;
+ }
+ }
+
+ return Result = MaxRegUse+NumExtraMaxRegUsers;
+}
+
/// SelectAddress - Add the specified node to the specified addressing mode,
/// returning true if it cannot be done.
bool ISel::SelectAddress(SDOperand N, X86AddressMode &AM) {
@@ -735,7 +776,7 @@
}
void ISel::EmitCMP(SDOperand LHS, SDOperand RHS) {
- unsigned Tmp1 = SelectExpr(LHS), Opc;
+ unsigned Opc;
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(RHS)) {
Opc = 0;
switch (RHS.getValueType()) {
@@ -746,6 +787,7 @@
case MVT::i32: Opc = X86::CMP32ri; break;
}
if (Opc) {
+ unsigned Tmp1 = SelectExpr(LHS);
BuildMI(BB, Opc, 2).addReg(Tmp1).addImm(CN->getValue());
return;
}
@@ -760,7 +802,14 @@
case MVT::f32:
case MVT::f64: Opc = X86::FUCOMIr; ContainsFPCode = true; break;
}
- unsigned Tmp2 = SelectExpr(RHS);
+ unsigned Tmp1, Tmp2;
+ if (getRegPressure(LHS) > getRegPressure(RHS)) {
+ Tmp1 = SelectExpr(LHS);
+ Tmp2 = SelectExpr(RHS);
+ } else {
+ Tmp2 = SelectExpr(RHS);
+ Tmp1 = SelectExpr(LHS);
+ }
BuildMI(BB, Opc, 2).addReg(Tmp1).addReg(Tmp2);
}
@@ -1149,7 +1198,7 @@
}
}
}
- Tmp1 = SelectExpr(N.getOperand(0));
+
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
Opc = 0;
if (CN->getValue() == 1) { // add X, 1 -> inc X
@@ -1169,6 +1218,7 @@
}
if (Opc) {
+ Tmp1 = SelectExpr(N.getOperand(0));
BuildMI(BB, Opc, 1, Result).addReg(Tmp1);
return Result;
}
@@ -1180,12 +1230,12 @@
case MVT::i32: Opc = X86::ADD32ri; break;
}
if (Opc) {
+ Tmp1 = SelectExpr(N.getOperand(0));
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(CN->getValue());
return Result;
}
}
- Tmp2 = SelectExpr(N.getOperand(1));
switch (N.getValueType()) {
default: assert(0 && "Cannot add this type!");
case MVT::i8: Opc = X86::ADD8rr; break;
@@ -1194,6 +1244,15 @@
case MVT::f32:
case MVT::f64: Opc = X86::FpADD; ContainsFPCode = true; break;
}
+
+ if (getRegPressure(N.getOperand(0)) > getRegPressure(N.getOperand(1))) {
+ Tmp1 = SelectExpr(N.getOperand(0));
+ Tmp2 = SelectExpr(N.getOperand(1));
+ } else {
+ Tmp2 = SelectExpr(N.getOperand(1));
+ Tmp1 = SelectExpr(N.getOperand(0));
+ }
+
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
return Result;
case ISD::SUB:
@@ -1212,7 +1271,6 @@
return Result;
}
- Tmp1 = SelectExpr(N.getOperand(0));
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
switch (N.getValueType()) {
default: assert(0 && "Cannot sub this type!");
@@ -1221,10 +1279,19 @@
case MVT::i16: Opc = X86::SUB16ri; break;
case MVT::i32: Opc = X86::SUB32ri; break;
}
+ Tmp1 = SelectExpr(N.getOperand(0));
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(CN->getValue());
return Result;
}
- Tmp2 = SelectExpr(N.getOperand(1));
+
+ if (getRegPressure(N.getOperand(0)) > getRegPressure(N.getOperand(1))) {
+ Tmp1 = SelectExpr(N.getOperand(0));
+ Tmp2 = SelectExpr(N.getOperand(1));
+ } else {
+ Tmp2 = SelectExpr(N.getOperand(1));
+ Tmp1 = SelectExpr(N.getOperand(0));
+ }
+
switch (N.getValueType()) {
default: assert(0 && "Cannot add this type!");
case MVT::i1:
@@ -1238,7 +1305,6 @@
return Result;
case ISD::AND:
- Tmp1 = SelectExpr(N.getOperand(0));
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
switch (N.getValueType()) {
default: assert(0 && "Cannot add this type!");
@@ -1247,10 +1313,19 @@
case MVT::i16: Opc = X86::AND16ri; break;
case MVT::i32: Opc = X86::AND32ri; break;
}
+ Tmp1 = SelectExpr(N.getOperand(0));
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(CN->getValue());
return Result;
}
- Tmp2 = SelectExpr(N.getOperand(1));
+
+ if (getRegPressure(N.getOperand(0)) > getRegPressure(N.getOperand(1))) {
+ Tmp1 = SelectExpr(N.getOperand(0));
+ Tmp2 = SelectExpr(N.getOperand(1));
+ } else {
+ Tmp2 = SelectExpr(N.getOperand(1));
+ Tmp1 = SelectExpr(N.getOperand(0));
+ }
+
switch (N.getValueType()) {
default: assert(0 && "Cannot add this type!");
case MVT::i1:
@@ -1261,8 +1336,8 @@
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
return Result;
case ISD::OR:
- Tmp1 = SelectExpr(N.getOperand(0));
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
+ Tmp1 = SelectExpr(N.getOperand(0));
switch (N.getValueType()) {
default: assert(0 && "Cannot add this type!");
case MVT::i1:
@@ -1273,7 +1348,15 @@
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(CN->getValue());
return Result;
}
- Tmp2 = SelectExpr(N.getOperand(1));
+
+ if (getRegPressure(N.getOperand(0)) > getRegPressure(N.getOperand(1))) {
+ Tmp1 = SelectExpr(N.getOperand(0));
+ Tmp2 = SelectExpr(N.getOperand(1));
+ } else {
+ Tmp2 = SelectExpr(N.getOperand(1));
+ Tmp1 = SelectExpr(N.getOperand(0));
+ }
+
switch (N.getValueType()) {
default: assert(0 && "Cannot add this type!");
case MVT::i1:
@@ -1284,8 +1367,8 @@
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
return Result;
case ISD::XOR:
- Tmp1 = SelectExpr(N.getOperand(0));
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
+ Tmp1 = SelectExpr(N.getOperand(0));
switch (N.getValueType()) {
default: assert(0 && "Cannot add this type!");
case MVT::i1:
@@ -1296,7 +1379,15 @@
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(CN->getValue());
return Result;
}
- Tmp2 = SelectExpr(N.getOperand(1));
+
+ if (getRegPressure(N.getOperand(0)) > getRegPressure(N.getOperand(1))) {
+ Tmp1 = SelectExpr(N.getOperand(0));
+ Tmp2 = SelectExpr(N.getOperand(1));
+ } else {
+ Tmp2 = SelectExpr(N.getOperand(1));
+ Tmp1 = SelectExpr(N.getOperand(0));
+ }
+
switch (N.getValueType()) {
default: assert(0 && "Cannot add this type!");
case MVT::i1:
@@ -1308,7 +1399,6 @@
return Result;
case ISD::MUL:
- Tmp1 = SelectExpr(N.getOperand(0));
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
Opc = 0;
switch (N.getValueType()) {
@@ -1318,11 +1408,19 @@
case MVT::i32: Opc = X86::IMUL32rri; break;
}
if (Opc) {
+ Tmp1 = SelectExpr(N.getOperand(0));
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(CN->getValue());
return Result;
}
}
- Tmp2 = SelectExpr(N.getOperand(1));
+
+ if (getRegPressure(N.getOperand(0)) > getRegPressure(N.getOperand(1))) {
+ Tmp1 = SelectExpr(N.getOperand(0));
+ Tmp2 = SelectExpr(N.getOperand(1));
+ } else {
+ Tmp2 = SelectExpr(N.getOperand(1));
+ Tmp1 = SelectExpr(N.getOperand(0));
+ }
switch (N.getValueType()) {
default: assert(0 && "Cannot add this type!");
case MVT::i8:
@@ -1342,8 +1440,13 @@
case ISD::SELECT:
// FIXME: implement folding of setcc into select.
if (N.getValueType() != MVT::i1 && N.getValueType() != MVT::i8) {
- Tmp2 = SelectExpr(N.getOperand(1));
- Tmp3 = SelectExpr(N.getOperand(2));
+ if (getRegPressure(N.getOperand(1)) > getRegPressure(N.getOperand(2))) {
+ Tmp2 = SelectExpr(N.getOperand(1));
+ Tmp3 = SelectExpr(N.getOperand(2));
+ } else {
+ Tmp3 = SelectExpr(N.getOperand(2));
+ Tmp2 = SelectExpr(N.getOperand(1));
+ }
EmitSelectCC(N.getOperand(0), N.getValueType(), Tmp2, Tmp3, Result);
return Result;
} else {
@@ -1365,8 +1468,6 @@
case ISD::UDIV:
case ISD::SREM:
case ISD::UREM: {
- Tmp1 = SelectExpr(N.getOperand(0));
-
if (N.getOpcode() == ISD::SDIV)
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
// FIXME: These special cases should be handled by the lowering impl!
@@ -1401,6 +1502,7 @@
NEGOpc = X86::NEG32r;
break;
}
+ Tmp1 = SelectExpr(N.getOperand(0));
BuildMI(BB, SAROpc, 2, TmpReg).addReg(Tmp1).addImm(Log-1);
unsigned TmpReg2 = MakeReg(N.getValueType());
BuildMI(BB, SHROpc, 2, TmpReg2).addReg(TmpReg).addImm(32-Log);
@@ -1415,7 +1517,13 @@
}
}
- Tmp2 = SelectExpr(N.getOperand(1));
+ if (getRegPressure(N.getOperand(0)) > getRegPressure(N.getOperand(1))) {
+ Tmp1 = SelectExpr(N.getOperand(0));
+ Tmp2 = SelectExpr(N.getOperand(1));
+ } else {
+ Tmp2 = SelectExpr(N.getOperand(1));
+ Tmp1 = SelectExpr(N.getOperand(0));
+ }
bool isSigned = N.getOpcode() == ISD::SDIV || N.getOpcode() == ISD::SREM;
bool isDiv = N.getOpcode() == ISD::SDIV || N.getOpcode() == ISD::UDIV;
@@ -1477,7 +1585,6 @@
}
case ISD::SHL:
- Tmp1 = SelectExpr(N.getOperand(0));
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
switch (N.getValueType()) {
default: assert(0 && "Cannot shift this type!");
@@ -1485,10 +1592,19 @@
case MVT::i16: Opc = X86::SHL16ri; break;
case MVT::i32: Opc = X86::SHL32ri; break;
}
+ Tmp1 = SelectExpr(N.getOperand(0));
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(CN->getValue());
return Result;
}
- Tmp2 = SelectExpr(N.getOperand(1));
+
+ if (getRegPressure(N.getOperand(0)) > getRegPressure(N.getOperand(1))) {
+ Tmp1 = SelectExpr(N.getOperand(0));
+ Tmp2 = SelectExpr(N.getOperand(1));
+ } else {
+ Tmp2 = SelectExpr(N.getOperand(1));
+ Tmp1 = SelectExpr(N.getOperand(0));
+ }
+
switch (N.getValueType()) {
default: assert(0 && "Cannot shift this type!");
case MVT::i8 : Opc = X86::SHL8rCL; break;
@@ -1499,7 +1615,6 @@
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
return Result;
case ISD::SRL:
- Tmp1 = SelectExpr(N.getOperand(0));
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
switch (N.getValueType()) {
default: assert(0 && "Cannot shift this type!");
@@ -1507,10 +1622,19 @@
case MVT::i16: Opc = X86::SHR16ri; break;
case MVT::i32: Opc = X86::SHR32ri; break;
}
+ Tmp1 = SelectExpr(N.getOperand(0));
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(CN->getValue());
return Result;
}
- Tmp2 = SelectExpr(N.getOperand(1));
+
+ if (getRegPressure(N.getOperand(0)) > getRegPressure(N.getOperand(1))) {
+ Tmp1 = SelectExpr(N.getOperand(0));
+ Tmp2 = SelectExpr(N.getOperand(1));
+ } else {
+ Tmp2 = SelectExpr(N.getOperand(1));
+ Tmp1 = SelectExpr(N.getOperand(0));
+ }
+
switch (N.getValueType()) {
default: assert(0 && "Cannot shift this type!");
case MVT::i8 : Opc = X86::SHR8rCL; break;
@@ -1521,7 +1645,6 @@
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
return Result;
case ISD::SRA:
- Tmp1 = SelectExpr(N.getOperand(0));
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
switch (N.getValueType()) {
default: assert(0 && "Cannot shift this type!");
@@ -1529,10 +1652,19 @@
case MVT::i16: Opc = X86::SAR16ri; break;
case MVT::i32: Opc = X86::SAR32ri; break;
}
+ Tmp1 = SelectExpr(N.getOperand(0));
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(CN->getValue());
return Result;
}
- Tmp2 = SelectExpr(N.getOperand(1));
+
+ if (getRegPressure(N.getOperand(0)) > getRegPressure(N.getOperand(1))) {
+ Tmp1 = SelectExpr(N.getOperand(0));
+ Tmp2 = SelectExpr(N.getOperand(1));
+ } else {
+ Tmp2 = SelectExpr(N.getOperand(1));
+ Tmp1 = SelectExpr(N.getOperand(0));
+ }
+
switch (N.getValueType()) {
default: assert(0 && "Cannot shift this type!");
case MVT::i8 : Opc = X86::SAR8rCL; break;
@@ -1553,7 +1685,6 @@
case ISD::LOAD: {
// The chain for this load is now lowered.
LoweredTokens.insert(SDOperand(Node, 1));
- Select(N.getOperand(0));
// Make sure we generate both values.
if (Result != 1)
@@ -1570,18 +1701,24 @@
case MVT::f32: Opc = X86::FLD32m; ContainsFPCode = true; break;
case MVT::f64: Opc = X86::FLD64m; ContainsFPCode = true; break;
}
+
if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N.getOperand(1))){
+ Select(N.getOperand(0));
addConstantPoolReference(BuildMI(BB, Opc, 4, Result), CP->getIndex());
} else {
X86AddressMode AM;
- SelectAddress(N.getOperand(1), AM);
+ if (getRegPressure(N.getOperand(0)) > getRegPressure(N.getOperand(1))) {
+ Select(N.getOperand(0));
+ SelectAddress(N.getOperand(1), AM);
+ } else {
+ SelectAddress(N.getOperand(1), AM);
+ Select(N.getOperand(0));
+ }
addFullAddress(BuildMI(BB, Opc, 4, Result), AM);
}
return Result;
}
case ISD::DYNAMIC_STACKALLOC:
- Select(N.getOperand(0));
-
// Generate both result values.
if (Result != 1)
ExprMap[N.getValue(1)] = 1; // Generate the token
@@ -1600,10 +1737,17 @@
}
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
+ Select(N.getOperand(0));
BuildMI(BB, X86::SUB32ri, 2, X86::ESP).addReg(X86::ESP)
.addImm(CN->getValue());
} else {
- Tmp1 = SelectExpr(N.getOperand(1));
+ if (getRegPressure(N.getOperand(0)) > getRegPressure(N.getOperand(1))) {
+ Select(N.getOperand(0));
+ Tmp1 = SelectExpr(N.getOperand(1));
+ } else {
+ Tmp1 = SelectExpr(N.getOperand(1));
+ Select(N.getOperand(0));
+ }
// Subtract size from stack pointer, thereby allocating some space.
BuildMI(BB, X86::SUB32rr, 2, X86::ESP).addReg(X86::ESP).addReg(Tmp1);
@@ -1618,16 +1762,24 @@
// The chain for this call is now lowered.
LoweredTokens.insert(N.getValue(Node->getNumValues()-1));
- Select(N.getOperand(0));
if (GlobalAddressSDNode *GASD =
dyn_cast<GlobalAddressSDNode>(N.getOperand(1))) {
+ Select(N.getOperand(0));
BuildMI(BB, X86::CALLpcrel32, 1).addGlobalAddress(GASD->getGlobal(),true);
} else if (ExternalSymbolSDNode *ESSDN =
dyn_cast<ExternalSymbolSDNode>(N.getOperand(1))) {
+ Select(N.getOperand(0));
BuildMI(BB, X86::CALLpcrel32,
1).addExternalSymbol(ESSDN->getSymbol(), true);
} else {
- Tmp1 = SelectExpr(N.getOperand(1));
+ if (getRegPressure(N.getOperand(0)) > getRegPressure(N.getOperand(1))) {
+ Select(N.getOperand(0));
+ Tmp1 = SelectExpr(N.getOperand(1));
+ } else {
+ Tmp1 = SelectExpr(N.getOperand(1));
+ Select(N.getOperand(0));
+ }
+
BuildMI(BB, X86::CALL32r, 1).addReg(Tmp1);
}
switch (Node->getValueType(0)) {
@@ -1688,7 +1840,6 @@
}
return;
case ISD::RET:
- Select(N.getOperand(0));
switch (N.getNumOperands()) {
default:
assert(0 && "Unknown return instruction!");
@@ -1696,8 +1847,15 @@
assert(N.getOperand(1).getValueType() == MVT::i32 &&
N.getOperand(2).getValueType() == MVT::i32 &&
"Unknown two-register value!");
- Tmp1 = SelectExpr(N.getOperand(1));
- Tmp2 = SelectExpr(N.getOperand(2));
+ if (getRegPressure(N.getOperand(1)) > getRegPressure(N.getOperand(2))) {
+ Tmp1 = SelectExpr(N.getOperand(1));
+ Tmp2 = SelectExpr(N.getOperand(2));
+ } else {
+ Tmp2 = SelectExpr(N.getOperand(2));
+ Tmp1 = SelectExpr(N.getOperand(1));
+ }
+ Select(N.getOperand(0));
+
BuildMI(BB, X86::MOV32rr, 1, X86::EAX).addReg(Tmp1);
BuildMI(BB, X86::MOV32rr, 1, X86::EDX).addReg(Tmp2);
// Declare that EAX & EDX are live on exit.
@@ -1705,7 +1863,13 @@
.addReg(X86::ESP);
break;
case 2:
- Tmp1 = SelectExpr(N.getOperand(1));
+ if (getRegPressure(N.getOperand(0)) > getRegPressure(N.getOperand(1))) {
+ Select(N.getOperand(0));
+ Tmp1 = SelectExpr(N.getOperand(1));
+ } else {
+ Tmp1 = SelectExpr(N.getOperand(1));
+ Select(N.getOperand(0));
+ }
switch (N.getOperand(1).getValueType()) {
default: assert(0 && "All other types should have been promoted!!");
case MVT::f64:
@@ -1720,6 +1884,7 @@
}
break;
case 1:
+ Select(N.getOperand(0));
break;
}
BuildMI(BB, X86::RET, 0); // Just emit a 'ret' instruction
@@ -1733,9 +1898,14 @@
}
case ISD::BRCOND: {
- Select(N.getOperand(0));
MachineBasicBlock *Dest =
cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
+
+ bool ChainFirst =
+ getRegPressure(N.getOperand(0)) > getRegPressure(N.getOperand(1));
+
+ if (ChainFirst) Select(N.getOperand(0));
+
// Try to fold a setcc into the branch. If this fails, emit a test/jne
// pair.
if (EmitBranchCC(Dest, N.getOperand(1))) {
@@ -1743,6 +1913,9 @@
BuildMI(BB, X86::TEST8rr, 2).addReg(Tmp1).addReg(Tmp1);
BuildMI(BB, X86::JNE, 1).addMBB(Dest);
}
+
+ if (!ChainFirst) Select(N.getOperand(0));
+
return;
}
case ISD::LOAD:
@@ -1751,10 +1924,8 @@
SelectExpr(N);
return;
case ISD::STORE: {
- Select(N.getOperand(0));
// Select the address.
X86AddressMode AM;
- SelectAddress(N.getOperand(2), AM);
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
Opc = 0;
@@ -1768,12 +1939,17 @@
case MVT::f64: break;
}
if (Opc) {
+ if (getRegPressure(N.getOperand(0)) > getRegPressure(N.getOperand(2))) {
+ Select(N.getOperand(0));
+ SelectAddress(N.getOperand(2), AM);
+ } else {
+ SelectAddress(N.getOperand(2), AM);
+ Select(N.getOperand(0));
+ }
addFullAddress(BuildMI(BB, Opc, 4+1), AM).addImm(CN->getValue());
return;
}
}
- Tmp1 = SelectExpr(N.getOperand(1));
-
switch (N.getOperand(1).getValueType()) {
default: assert(0 && "Cannot store this type!");
case MVT::i1:
@@ -1783,6 +1959,21 @@
case MVT::f32: Opc = X86::FST32m; ContainsFPCode = true; break;
case MVT::f64: Opc = X86::FST64m; ContainsFPCode = true; break;
}
+
+ std::vector<std::pair<unsigned, unsigned> > RP;
+ RP.push_back(std::make_pair(getRegPressure(N.getOperand(0)), 0));
+ RP.push_back(std::make_pair(getRegPressure(N.getOperand(1)), 1));
+ RP.push_back(std::make_pair(getRegPressure(N.getOperand(2)), 2));
+ std::sort(RP.begin(), RP.end());
+
+ for (unsigned i = 0; i != 3; ++i)
+ switch (RP[2-i].second) {
+ default: assert(0 && "Unknown operand number!");
+ case 0: Select(N.getOperand(0)); break;
+ case 1: Tmp1 = SelectExpr(N.getOperand(1)); break;
+ case 2: SelectAddress(N.getOperand(2), AM);
+ }
+
addFullAddress(BuildMI(BB, Opc, 4+1), AM).addReg(Tmp1);
return;
}
More information about the llvm-commits
mailing list