[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp
Chris Lattner
lattner at cs.uiuc.edu
Mon Jan 17 17:06:40 PST 2005
Changes in directory llvm/lib/Target/X86:
X86ISelPattern.cpp updated: 1.67 -> 1.68
---
Log message:
Fix a problem where probing for addressing modes caused expressions to be
emitted too early. In particular, this fixes
Regression/CodeGen/X86/regpressure.ll:regpressure3.
This also improves the 2nd basic block in 164.gzip:flush_block, which went from
.LBBflush_block_1: # loopentry.1.i
movzx %EAX, WORD PTR [dyn_ltree + 20]
movzx %ECX, WORD PTR [dyn_ltree + 16]
mov DWORD PTR [%ESP + 32], %ECX
movzx %ECX, WORD PTR [dyn_ltree + 12]
movzx %EDX, WORD PTR [dyn_ltree + 8]
movzx %EBX, WORD PTR [dyn_ltree + 4]
mov DWORD PTR [%ESP + 36], %EBX
movzx %EBX, WORD PTR [dyn_ltree]
add DWORD PTR [%ESP + 36], %EBX
add %EDX, DWORD PTR [%ESP + 36]
add %ECX, %EDX
add DWORD PTR [%ESP + 32], %ECX
add %EAX, DWORD PTR [%ESP + 32]
movzx %ECX, WORD PTR [dyn_ltree + 24]
add %EAX, %ECX
mov %ECX, 0
mov %EDX, %ECX
to
.LBBflush_block_1: # loopentry.1.i
movzx %EAX, WORD PTR [dyn_ltree]
movzx %ECX, WORD PTR [dyn_ltree + 4]
add %ECX, %EAX
movzx %EAX, WORD PTR [dyn_ltree + 8]
add %EAX, %ECX
movzx %ECX, WORD PTR [dyn_ltree + 12]
add %ECX, %EAX
movzx %EAX, WORD PTR [dyn_ltree + 16]
add %EAX, %ECX
movzx %ECX, WORD PTR [dyn_ltree + 20]
add %ECX, %EAX
movzx %EAX, WORD PTR [dyn_ltree + 24]
add %ECX, %EAX
mov %EAX, 0
mov %EDX, %EAX
... which results in less spilling in the function.
This change alone speeds up 164.gzip from 37.23s to 36.24s on apoc. The
default isel takes 37.31s.
---
Diffs of the changes: (+110 -33)
Index: llvm/lib/Target/X86/X86ISelPattern.cpp
diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.67 llvm/lib/Target/X86/X86ISelPattern.cpp:1.68
--- llvm/lib/Target/X86/X86ISelPattern.cpp:1.67 Mon Jan 17 17:02:13 2005
+++ llvm/lib/Target/X86/X86ISelPattern.cpp Mon Jan 17 19:06:26 2005
@@ -300,7 +300,31 @@
}
-
+namespace {
+ /// X86ISelAddressMode - This corresponds to X86AddressMode, but uses
+ /// SDOperand's instead of register numbers for the leaves of the matched
+ /// tree.
+ struct X86ISelAddressMode {
+ enum {
+ RegBase,
+ FrameIndexBase,
+ } BaseType;
+
+ struct { // This is really a union, discriminated by BaseType!
+ SDOperand Reg;
+ int FrameIndex;
+ } Base;
+
+ unsigned Scale;
+ SDOperand IndexReg;
+ unsigned Disp;
+ GlobalValue *GV;
+
+ X86ISelAddressMode()
+ : BaseType(RegBase), Scale(1), IndexReg(), Disp(), GV(0) {
+ }
+ };
+}
namespace {
@@ -352,7 +376,10 @@
void EmitSelectCC(SDOperand Cond, MVT::ValueType SVT,
unsigned RTrue, unsigned RFalse, unsigned RDest);
unsigned SelectExpr(SDOperand N);
- bool SelectAddress(SDOperand N, X86AddressMode &AM);
+
+ X86AddressMode SelectAddrExprs(const X86ISelAddressMode &IAM);
+ bool MatchAddress(SDOperand N, X86ISelAddressMode &AM);
+ void SelectAddress(SDOperand N, X86AddressMode &AM);
void Select(SDOperand N);
};
}
@@ -464,14 +491,62 @@
return Result;
}
-/// SelectAddress - Add the specified node to the specified addressing mode,
-/// returning true if it cannot be done.
-bool ISel::SelectAddress(SDOperand N, X86AddressMode &AM) {
+X86AddressMode ISel::SelectAddrExprs(const X86ISelAddressMode &IAM) {
+ X86AddressMode Result;
+
+ // If we need to emit two register operands, emit the one with the highest
+ // register pressure first.
+ if (IAM.BaseType == X86ISelAddressMode::RegBase &&
+ IAM.Base.Reg.Val && IAM.IndexReg.Val) {
+ if (getRegPressure(IAM.Base.Reg) > getRegPressure(IAM.IndexReg)) {
+ Result.Base.Reg = SelectExpr(IAM.Base.Reg);
+ Result.IndexReg = SelectExpr(IAM.IndexReg);
+ } else {
+ Result.IndexReg = SelectExpr(IAM.IndexReg);
+ Result.Base.Reg = SelectExpr(IAM.Base.Reg);
+ }
+ } else if (IAM.BaseType == X86ISelAddressMode::RegBase && IAM.Base.Reg.Val) {
+ Result.Base.Reg = SelectExpr(IAM.Base.Reg);
+ } else if (IAM.IndexReg.Val) {
+ Result.IndexReg = SelectExpr(IAM.IndexReg);
+ }
+
+ switch (IAM.BaseType) {
+ case X86ISelAddressMode::RegBase:
+ Result.BaseType = X86AddressMode::RegBase;
+ break;
+ case X86ISelAddressMode::FrameIndexBase:
+ Result.BaseType = X86AddressMode::FrameIndexBase;
+ Result.Base.FrameIndex = IAM.Base.FrameIndex;
+ break;
+ default:
+ assert(0 && "Unknown base type!");
+ break;
+ }
+ Result.Scale = IAM.Scale;
+ Result.Disp = IAM.Disp;
+ Result.GV = IAM.GV;
+ return Result;
+}
+
+/// SelectAddress - Pattern match the maximal addressing mode for this node and
+/// emit all of the leaf registers.
+void ISel::SelectAddress(SDOperand N, X86AddressMode &AM) {
+ X86ISelAddressMode IAM;
+ MatchAddress(N, IAM);
+ AM = SelectAddrExprs(IAM);
+}
+
+/// MatchAddress - Add the specified node to the specified addressing mode,
+/// returning true if it cannot be done. This just pattern matches for the
+/// addressing mode, it does not cause any code to be emitted. For that, use
+/// SelectAddress.
+bool ISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM) {
switch (N.getOpcode()) {
default: break;
case ISD::FrameIndex:
- if (AM.BaseType == X86AddressMode::RegBase && AM.Base.Reg == 0) {
- AM.BaseType = X86AddressMode::FrameIndexBase;
+ if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base.Reg.Val == 0) {
+ AM.BaseType = X86ISelAddressMode::FrameIndexBase;
AM.Base.FrameIndex = cast<FrameIndexSDNode>(N)->getIndex();
return false;
}
@@ -490,7 +565,7 @@
// if so.
if (ExprMap.count(N)) break;
- if (AM.IndexReg == 0 && AM.Scale == 1)
+ if (AM.IndexReg.Val == 0 && AM.Scale == 1)
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.Val->getOperand(1))) {
unsigned Val = CN->getValue();
if (Val == 1 || Val == 2 || Val == 3) {
@@ -502,12 +577,12 @@
// constant into the disp field here.
if (ShVal.Val->getOpcode() == ISD::ADD && !ExprMap.count(ShVal) &&
isa<ConstantSDNode>(ShVal.Val->getOperand(1))) {
- AM.IndexReg = SelectExpr(ShVal.Val->getOperand(0));
+ AM.IndexReg = ShVal.Val->getOperand(0);
ConstantSDNode *AddVal =
cast<ConstantSDNode>(ShVal.Val->getOperand(1));
AM.Disp += AddVal->getValue() << Val;
} else {
- AM.IndexReg = SelectExpr(ShVal);
+ AM.IndexReg = ShVal;
}
return false;
}
@@ -519,26 +594,26 @@
if (ExprMap.count(N)) break;
// X*[3,5,9] -> X+X*[2,4,8]
- if (AM.IndexReg == 0 && AM.BaseType == X86AddressMode::RegBase &&
- AM.Base.Reg == 0)
+ if (AM.IndexReg.Val == 0 && AM.BaseType == X86ISelAddressMode::RegBase &&
+ AM.Base.Reg.Val == 0)
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.Val->getOperand(1)))
if (CN->getValue() == 3 || CN->getValue() == 5 || CN->getValue() == 9) {
AM.Scale = unsigned(CN->getValue())-1;
SDOperand MulVal = N.Val->getOperand(0);
- unsigned Reg;
+ SDOperand Reg;
// Okay, we know that we have a scale by now. However, if the scaled
// value is an add of something and a constant, we can fold the
// constant into the disp field here.
if (MulVal.Val->getOpcode() == ISD::ADD && !ExprMap.count(MulVal) &&
isa<ConstantSDNode>(MulVal.Val->getOperand(1))) {
- Reg = SelectExpr(MulVal.Val->getOperand(0));
+ Reg = MulVal.Val->getOperand(0);
ConstantSDNode *AddVal =
cast<ConstantSDNode>(MulVal.Val->getOperand(1));
AM.Disp += AddVal->getValue() * CN->getValue();
} else {
- Reg = SelectExpr(N.Val->getOperand(0));
+ Reg = N.Val->getOperand(0);
}
AM.IndexReg = AM.Base.Reg = Reg;
@@ -551,13 +626,13 @@
// so.
if (ExprMap.count(N)) break;
- X86AddressMode Backup = AM;
- if (!SelectAddress(N.Val->getOperand(0), AM) &&
- !SelectAddress(N.Val->getOperand(1), AM))
+ X86ISelAddressMode Backup = AM;
+ if (!MatchAddress(N.Val->getOperand(0), AM) &&
+ !MatchAddress(N.Val->getOperand(1), AM))
return false;
AM = Backup;
- if (!SelectAddress(N.Val->getOperand(1), AM) &&
- !SelectAddress(N.Val->getOperand(0), AM))
+ if (!MatchAddress(N.Val->getOperand(1), AM) &&
+ !MatchAddress(N.Val->getOperand(0), AM))
return false;
AM = Backup;
break;
@@ -565,10 +640,10 @@
}
// Is the base register already occupied?
- if (AM.BaseType != X86AddressMode::RegBase || AM.Base.Reg) {
+ if (AM.BaseType != X86ISelAddressMode::RegBase || AM.Base.Reg.Val) {
// If so, check to see if the scale index register is set.
- if (AM.IndexReg == 0) {
- AM.IndexReg = SelectExpr(N);
+ if (AM.IndexReg.Val == 0) {
+ AM.IndexReg = N;
AM.Scale = 1;
return false;
}
@@ -578,8 +653,8 @@
}
// Default, generate it as a register.
- AM.BaseType = X86AddressMode::RegBase;
- AM.Base.Reg = SelectExpr(N);
+ AM.BaseType = X86ISelAddressMode::RegBase;
+ AM.Base.Reg = N;
return false;
}
@@ -1056,6 +1131,7 @@
void ISel::EmitFoldedLoad(SDOperand Op, X86AddressMode &AM) {
SDOperand Chain = Op.getOperand(0);
SDOperand Address = Op.getOperand(1);
+
if (getRegPressure(Chain) > getRegPressure(Address)) {
Select(Chain);
SelectAddress(Address, AM);
@@ -1503,15 +1579,16 @@
// See if we can codegen this as an LEA to fold operations together.
if (N.getValueType() == MVT::i32) {
- X86AddressMode AM;
- if (!SelectAddress(Op0, AM) && !SelectAddress(Op1, AM)) {
+ X86ISelAddressMode AM;
+ if (!MatchAddress(Op0, AM) && !MatchAddress(Op1, AM)) {
// If this is not just an add, emit the LEA. For a simple add (like
// reg+reg or reg+imm), we just emit an add. It might be a good idea to
// leave this as LEA, then peephole it to 'ADD' after two address elim
// happens.
- if (AM.Scale != 1 || AM.BaseType == X86AddressMode::FrameIndexBase ||
- AM.GV || (AM.Base.Reg && AM.IndexReg && AM.Disp)) {
- addFullAddress(BuildMI(BB, X86::LEA32r, 4, Result), AM);
+ if (AM.Scale != 1 || AM.BaseType == X86ISelAddressMode::FrameIndexBase||
+ AM.GV || (AM.Base.Reg.Val && AM.IndexReg.Val && AM.Disp)) {
+ X86AddressMode XAM = SelectAddrExprs(AM);
+ addFullAddress(BuildMI(BB, X86::LEA32r, 4, Result), XAM);
return Result;
}
}
@@ -1646,9 +1723,9 @@
case 3:
case 5:
case 9:
- X86AddressMode AM;
// Remove N from exprmap so SelectAddress doesn't get confused.
ExprMap.erase(N);
+ X86AddressMode AM;
SelectAddress(N, AM);
// Restore it to the map.
ExprMap[N] = Result;
@@ -2436,12 +2513,12 @@
LoweredTokens.insert(TheLoad.getValue(1));
Select(Chain);
-
Select(TheLoad.getOperand(0));
+
X86AddressMode AM;
SelectAddress(TheLoad.getOperand(1), AM);
unsigned Reg = SelectExpr(Op1);
- addFullAddress(BuildMI(BB, Opc, 4+1),AM).addReg(Reg);
+ addFullAddress(BuildMI(BB, Opc, 4+1), AM).addReg(Reg);
return true;
}
More information about the llvm-commits
mailing list