Fold constant adds into loads and stores to frame indices.

For the following code:
double %ext(int %A.0__, long %A.1__) {
        %A_addr = alloca %typedef.DComplex              ; <%typedef.DComplex*> [#uses=2]
        %tmp.1 = cast %typedef.DComplex* %A_addr to int*                ; <int*> [#uses=1]
        store int %A.0__, int* %tmp.1
        %tmp.2 = getelementptr %typedef.DComplex* %A_addr, int 0, uint 1                ; <double*> [#uses=2]
        %tmp.3 = cast double* %tmp.2 to long*           ; <long*> [#uses=1]
        store long %A.1__, long* %tmp.3
        %tmp.5 = load double* %tmp.2            ; <double> [#uses=1]
        ret double %tmp.5
}

We now generate:
_ext:
.LBB_ext_0:     ;
        stw r3, -12(r1)
        stw r4, -8(r1)
        stw r5, -4(r1)
        lfd f1, -8(r1)
        blr

Instead of:
_ext:
.LBB_ext_0:     ;
        stw r3, -12(r1)
        addi r2, r1, -12
        stw r4, 4(r2)
        stw r5, 8(r2)
        lfd f1, 4(r2)
        blr

This also fires hundreds of times on MultiSource.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22533 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Nate Begeman 2005-07-28 03:02:05 +00:00
parent 4418c2b3ac
commit 2a05c8e260

View File

@ -511,7 +511,7 @@ LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
namespace {
Statistic<>Recorded("ppc-codegen", "Number of recording ops emitted");
Statistic<>FusedFP("ppc-codegen", "Number of fused fp operations");
Statistic<>MultiBranch("ppc-codegen", "Number of setcc logical ops collapsed");
Statistic<>FrameOff("ppc-codegen", "Number of frame idx offsets collapsed");
//===--------------------------------------------------------------------===//
/// ISel - PPC32 specific code to select PPC32 machine instructions for
/// SelectionDAG operations.
@ -569,7 +569,7 @@ public:
unsigned SelectExpr(SDOperand N, bool Recording=false);
void Select(SDOperand N);
bool SelectAddr(SDOperand N, unsigned& Reg, int& offset);
unsigned SelectAddr(SDOperand N, unsigned& Reg, int& offset);
void SelectBranchCC(SDOperand N);
};
@ -1189,7 +1189,6 @@ unsigned ISel::SelectCCExpr(SDOperand N, unsigned& Opc, bool &Inv,
break;
case ISD::OR:
case ISD::AND:
++MultiBranch;
Tmp1 = SelectCCExpr(N.getOperand(0), Opc, Inv0, Idx0);
Tmp2 = SelectCCExpr(N.getOperand(1), Opc1, Inv1, Idx1);
CROpc = getCROpForSetCC(N.getOpcode(), Inv0, Inv1);
@ -1213,21 +1212,30 @@ unsigned ISel::SelectCCExpr(SDOperand N, unsigned& Opc, bool &Inv,
}
/// Check to see if the load is a constant offset from a base register
bool ISel::SelectAddr(SDOperand N, unsigned& Reg, int& offset)
unsigned ISel::SelectAddr(SDOperand N, unsigned& Reg, int& offset)
{
unsigned imm = 0, opcode = N.getOpcode();
if (N.getOpcode() == ISD::ADD) {
Reg = SelectExpr(N.getOperand(0));
bool isFrame = N.getOperand(0).getOpcode() == ISD::FrameIndex;
if (1 == getImmediateForOpcode(N.getOperand(1), opcode, imm)) {
offset = imm;
return false;
if (isFrame) {
++FrameOff;
Reg = cast<FrameIndexSDNode>(N.getOperand(0))->getIndex();
return 1;
} else {
Reg = SelectExpr(N.getOperand(0));
return 0;
}
} else {
Reg = SelectExpr(N.getOperand(0));
offset = SelectExpr(N.getOperand(1));
return 2;
}
offset = SelectExpr(N.getOperand(1));
return true;
}
Reg = SelectExpr(N);
offset = 0;
return false;
return 0;
}
void ISel::SelectBranchCC(SDOperand N)
@ -1443,12 +1451,18 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
}
} else {
int offset;
bool idx = SelectAddr(Address, Tmp1, offset);
if (idx) {
switch(SelectAddr(Address, Tmp1, offset)) {
default: assert(0 && "Unhandled return value from SelectAddr");
case 0: // imm offset, no frame, no index
BuildMI(BB, Opc, 2, Result).addSImm(offset).addReg(Tmp1);
break;
case 1: // imm offset + frame index
addFrameReference(BuildMI(BB, Opc, 2, Result), (int)Tmp1, offset);
break;
case 2: // base+index addressing
Opc = IndexedOpForOp(Opc);
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(offset);
} else {
BuildMI(BB, Opc, 2, Result).addSImm(offset).addReg(Tmp1);
break;
}
}
return Result;
@ -2495,12 +2509,18 @@ void ISel::Select(SDOperand N) {
}
} else {
int offset;
bool idx = SelectAddr(Address, Tmp2, offset);
if (idx) {
switch(SelectAddr(Address, Tmp2, offset)) {
default: assert(0 && "Unhandled return value from SelectAddr");
case 0: // imm offset, no frame, no index
BuildMI(BB, Opc, 3).addReg(Tmp1).addSImm(offset).addReg(Tmp2);
break;
case 1: // imm offset + frame index
addFrameReference(BuildMI(BB, Opc, 3).addReg(Tmp1), (int)Tmp2, offset);
break;
case 2: // base+index addressing
Opc = IndexedOpForOp(Opc);
BuildMI(BB, Opc, 3).addReg(Tmp1).addReg(Tmp2).addReg(offset);
} else {
BuildMI(BB, Opc, 3).addReg(Tmp1).addImm(offset).addReg(Tmp2);
break;
}
}
return;