mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-29 15:37:46 +00:00
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:
parent
4418c2b3ac
commit
2a05c8e260
@ -511,7 +511,7 @@ LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
|
|||||||
namespace {
|
namespace {
|
||||||
Statistic<>Recorded("ppc-codegen", "Number of recording ops emitted");
|
Statistic<>Recorded("ppc-codegen", "Number of recording ops emitted");
|
||||||
Statistic<>FusedFP("ppc-codegen", "Number of fused fp operations");
|
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
|
/// ISel - PPC32 specific code to select PPC32 machine instructions for
|
||||||
/// SelectionDAG operations.
|
/// SelectionDAG operations.
|
||||||
@ -569,7 +569,7 @@ public:
|
|||||||
unsigned SelectExpr(SDOperand N, bool Recording=false);
|
unsigned SelectExpr(SDOperand N, bool Recording=false);
|
||||||
void Select(SDOperand N);
|
void Select(SDOperand N);
|
||||||
|
|
||||||
bool SelectAddr(SDOperand N, unsigned& Reg, int& offset);
|
unsigned SelectAddr(SDOperand N, unsigned& Reg, int& offset);
|
||||||
void SelectBranchCC(SDOperand N);
|
void SelectBranchCC(SDOperand N);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1189,7 +1189,6 @@ unsigned ISel::SelectCCExpr(SDOperand N, unsigned& Opc, bool &Inv,
|
|||||||
break;
|
break;
|
||||||
case ISD::OR:
|
case ISD::OR:
|
||||||
case ISD::AND:
|
case ISD::AND:
|
||||||
++MultiBranch;
|
|
||||||
Tmp1 = SelectCCExpr(N.getOperand(0), Opc, Inv0, Idx0);
|
Tmp1 = SelectCCExpr(N.getOperand(0), Opc, Inv0, Idx0);
|
||||||
Tmp2 = SelectCCExpr(N.getOperand(1), Opc1, Inv1, Idx1);
|
Tmp2 = SelectCCExpr(N.getOperand(1), Opc1, Inv1, Idx1);
|
||||||
CROpc = getCROpForSetCC(N.getOpcode(), Inv0, Inv1);
|
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
|
/// 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();
|
unsigned imm = 0, opcode = N.getOpcode();
|
||||||
if (N.getOpcode() == ISD::ADD) {
|
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)) {
|
if (1 == getImmediateForOpcode(N.getOperand(1), opcode, imm)) {
|
||||||
offset = 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);
|
Reg = SelectExpr(N);
|
||||||
offset = 0;
|
offset = 0;
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ISel::SelectBranchCC(SDOperand N)
|
void ISel::SelectBranchCC(SDOperand N)
|
||||||
@ -1443,12 +1451,18 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int offset;
|
int offset;
|
||||||
bool idx = SelectAddr(Address, Tmp1, offset);
|
switch(SelectAddr(Address, Tmp1, offset)) {
|
||||||
if (idx) {
|
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);
|
Opc = IndexedOpForOp(Opc);
|
||||||
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(offset);
|
BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(offset);
|
||||||
} else {
|
break;
|
||||||
BuildMI(BB, Opc, 2, Result).addSImm(offset).addReg(Tmp1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
@ -2495,12 +2509,18 @@ void ISel::Select(SDOperand N) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int offset;
|
int offset;
|
||||||
bool idx = SelectAddr(Address, Tmp2, offset);
|
switch(SelectAddr(Address, Tmp2, offset)) {
|
||||||
if (idx) {
|
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);
|
Opc = IndexedOpForOp(Opc);
|
||||||
BuildMI(BB, Opc, 3).addReg(Tmp1).addReg(Tmp2).addReg(offset);
|
BuildMI(BB, Opc, 3).addReg(Tmp1).addReg(Tmp2).addReg(offset);
|
||||||
} else {
|
break;
|
||||||
BuildMI(BB, Opc, 3).addReg(Tmp1).addImm(offset).addReg(Tmp2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user