mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-21 06:30:16 +00:00
collect a few statistics, factor constants (constant loading and mult), fix logic operation pattern matchs, supress FP div when int dividing by a constant
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21156 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a844b017a6
commit
a32b9e31c6
@ -39,6 +39,9 @@ namespace llvm {
|
|||||||
cl::opt<bool> EnableAlphaFTOI("enable-alpha-ftoi",
|
cl::opt<bool> EnableAlphaFTOI("enable-alpha-ftoi",
|
||||||
cl::desc("Enable use of ftoi* and itof* instructions (ev6 and higher)"),
|
cl::desc("Enable use of ftoi* and itof* instructions (ev6 and higher)"),
|
||||||
cl::Hidden);
|
cl::Hidden);
|
||||||
|
cl::opt<bool> EnableAlphaCount("enable-alpha-count",
|
||||||
|
cl::desc("Print estimates on live ins and outs"),
|
||||||
|
cl::Hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -353,6 +356,10 @@ class ISel : public SelectionDAGISel {
|
|||||||
//CCInvMap sometimes (SetNE) we have the inverse CC code for free
|
//CCInvMap sometimes (SetNE) we have the inverse CC code for free
|
||||||
std::map<SDOperand, unsigned> CCInvMap;
|
std::map<SDOperand, unsigned> CCInvMap;
|
||||||
|
|
||||||
|
int count_ins;
|
||||||
|
int count_outs;
|
||||||
|
bool has_sym;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM)
|
ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM)
|
||||||
{}
|
{}
|
||||||
@ -361,9 +368,21 @@ public:
|
|||||||
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
|
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
|
||||||
virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
||||||
DEBUG(BB->dump());
|
DEBUG(BB->dump());
|
||||||
|
count_ins = 0;
|
||||||
|
count_outs = 0;
|
||||||
|
has_sym = false;
|
||||||
|
|
||||||
// Codegen the basic block.
|
// Codegen the basic block.
|
||||||
ISelDAG = &DAG;
|
ISelDAG = &DAG;
|
||||||
Select(DAG.getRoot());
|
Select(DAG.getRoot());
|
||||||
|
|
||||||
|
if(has_sym)
|
||||||
|
++count_ins;
|
||||||
|
if(EnableAlphaCount)
|
||||||
|
std::cerr << "COUNT: " << BB->getParent()->getFunction ()->getName() << " "
|
||||||
|
<< BB->getNumber() << " "
|
||||||
|
<< count_ins << " "
|
||||||
|
<< count_outs << "\n";
|
||||||
|
|
||||||
// Clear state used for selection.
|
// Clear state used for selection.
|
||||||
ExprMap.clear();
|
ExprMap.clear();
|
||||||
@ -388,6 +407,27 @@ public:
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Factorize a number using the list of constants
|
||||||
|
static bool factorize(int v[], int res[], int size, uint64_t c)
|
||||||
|
{
|
||||||
|
bool cont = true;
|
||||||
|
while (c != 1 && cont)
|
||||||
|
{
|
||||||
|
cont = false;
|
||||||
|
for(int i = 0; i < size; ++i)
|
||||||
|
{
|
||||||
|
if (c % v[i] == 0)
|
||||||
|
{
|
||||||
|
c /= v[i];
|
||||||
|
++res[i];
|
||||||
|
cont=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return c == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//Shamelessly adapted from PPC32
|
//Shamelessly adapted from PPC32
|
||||||
// Structure used to return the necessary information to codegen an SDIV as
|
// Structure used to return the necessary information to codegen an SDIV as
|
||||||
// a multiply.
|
// a multiply.
|
||||||
@ -975,11 +1015,13 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
|
|||||||
if (Address.getOpcode() == ISD::GlobalAddress) {
|
if (Address.getOpcode() == ISD::GlobalAddress) {
|
||||||
AlphaLowering.restoreGP(BB);
|
AlphaLowering.restoreGP(BB);
|
||||||
Opc = GetSymVersion(Opc);
|
Opc = GetSymVersion(Opc);
|
||||||
|
has_sym = true;
|
||||||
BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
|
BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
|
||||||
}
|
}
|
||||||
else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
|
else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
|
||||||
AlphaLowering.restoreGP(BB);
|
AlphaLowering.restoreGP(BB);
|
||||||
Opc = GetSymVersion(Opc);
|
Opc = GetSymVersion(Opc);
|
||||||
|
has_sym = true;
|
||||||
BuildMI(BB, Opc, 1, Result).addConstantPoolIndex(CP->getIndex());
|
BuildMI(BB, Opc, 1, Result).addConstantPoolIndex(CP->getIndex());
|
||||||
}
|
}
|
||||||
else if(Address.getOpcode() == ISD::FrameIndex) {
|
else if(Address.getOpcode() == ISD::FrameIndex) {
|
||||||
@ -1050,12 +1092,14 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
|
|||||||
|
|
||||||
if (Address.getOpcode() == ISD::GlobalAddress) {
|
if (Address.getOpcode() == ISD::GlobalAddress) {
|
||||||
AlphaLowering.restoreGP(BB);
|
AlphaLowering.restoreGP(BB);
|
||||||
|
has_sym = true;
|
||||||
BuildMI(BB, Alpha::LDS_SYM, 1, Tmp1).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
|
BuildMI(BB, Alpha::LDS_SYM, 1, Tmp1).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
|
||||||
}
|
}
|
||||||
else if (ConstantPoolSDNode *CP =
|
else if (ConstantPoolSDNode *CP =
|
||||||
dyn_cast<ConstantPoolSDNode>(N.getOperand(1)))
|
dyn_cast<ConstantPoolSDNode>(N.getOperand(1)))
|
||||||
{
|
{
|
||||||
AlphaLowering.restoreGP(BB);
|
AlphaLowering.restoreGP(BB);
|
||||||
|
has_sym = true;
|
||||||
BuildMI(BB, Alpha::LDS_SYM, 1, Tmp1).addConstantPoolIndex(CP->getIndex());
|
BuildMI(BB, Alpha::LDS_SYM, 1, Tmp1).addConstantPoolIndex(CP->getIndex());
|
||||||
}
|
}
|
||||||
else if(Address.getOpcode() == ISD::FrameIndex) {
|
else if(Address.getOpcode() == ISD::FrameIndex) {
|
||||||
@ -1246,11 +1290,13 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
|||||||
if (Address.getOpcode() == ISD::GlobalAddress) {
|
if (Address.getOpcode() == ISD::GlobalAddress) {
|
||||||
AlphaLowering.restoreGP(BB);
|
AlphaLowering.restoreGP(BB);
|
||||||
Opc = GetSymVersion(Opc);
|
Opc = GetSymVersion(Opc);
|
||||||
|
has_sym = true;
|
||||||
BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
|
BuildMI(BB, Opc, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
|
||||||
}
|
}
|
||||||
else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
|
else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
|
||||||
AlphaLowering.restoreGP(BB);
|
AlphaLowering.restoreGP(BB);
|
||||||
Opc = GetSymVersion(Opc);
|
Opc = GetSymVersion(Opc);
|
||||||
|
has_sym = true;
|
||||||
BuildMI(BB, Opc, 1, Result).addConstantPoolIndex(CP->getIndex());
|
BuildMI(BB, Opc, 1, Result).addConstantPoolIndex(CP->getIndex());
|
||||||
}
|
}
|
||||||
else if(Address.getOpcode() == ISD::FrameIndex) {
|
else if(Address.getOpcode() == ISD::FrameIndex) {
|
||||||
@ -1267,6 +1313,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
|||||||
|
|
||||||
case ISD::GlobalAddress:
|
case ISD::GlobalAddress:
|
||||||
AlphaLowering.restoreGP(BB);
|
AlphaLowering.restoreGP(BB);
|
||||||
|
has_sym = true;
|
||||||
BuildMI(BB, Alpha::LOAD_ADDR, 1, Result)
|
BuildMI(BB, Alpha::LOAD_ADDR, 1, Result)
|
||||||
.addGlobalAddress(cast<GlobalAddressSDNode>(N)->getGlobal());
|
.addGlobalAddress(cast<GlobalAddressSDNode>(N)->getGlobal());
|
||||||
return Result;
|
return Result;
|
||||||
@ -1343,6 +1390,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
|||||||
//if (GASD->getGlobal()->isExternal()) {
|
//if (GASD->getGlobal()->isExternal()) {
|
||||||
//use safe calling convention
|
//use safe calling convention
|
||||||
AlphaLowering.restoreGP(BB);
|
AlphaLowering.restoreGP(BB);
|
||||||
|
has_sym = true;
|
||||||
BuildMI(BB, Alpha::CALL, 1).addGlobalAddress(GASD->getGlobal(),true);
|
BuildMI(BB, Alpha::CALL, 1).addGlobalAddress(GASD->getGlobal(),true);
|
||||||
//} else {
|
//} else {
|
||||||
//use PC relative branch call
|
//use PC relative branch call
|
||||||
@ -1353,6 +1401,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
|||||||
dyn_cast<ExternalSymbolSDNode>(N.getOperand(1)))
|
dyn_cast<ExternalSymbolSDNode>(N.getOperand(1)))
|
||||||
{
|
{
|
||||||
AlphaLowering.restoreGP(BB);
|
AlphaLowering.restoreGP(BB);
|
||||||
|
has_sym = true;
|
||||||
BuildMI(BB, Alpha::CALL, 1).addExternalSymbol(ESSDN->getSymbol(), true);
|
BuildMI(BB, Alpha::CALL, 1).addExternalSymbol(ESSDN->getSymbol(), true);
|
||||||
} else {
|
} else {
|
||||||
//no need to restore GP as we are doing an indirect call
|
//no need to restore GP as we are doing an indirect call
|
||||||
@ -1383,8 +1432,9 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
|||||||
|
|
||||||
case ISD::SIGN_EXTEND_INREG:
|
case ISD::SIGN_EXTEND_INREG:
|
||||||
{
|
{
|
||||||
//do SDIV opt for all levels of ints
|
//do SDIV opt for all levels of ints if not dividing by a constant
|
||||||
if (EnableAlphaIDIV && N.getOperand(0).getOpcode() == ISD::SDIV)
|
if (EnableAlphaIDIV && N.getOperand(0).getOpcode() == ISD::SDIV
|
||||||
|
&& N.getOperand(0).getOperand(1).getOpcode() != ISD::Constant)
|
||||||
{
|
{
|
||||||
unsigned Tmp4 = MakeReg(MVT::f64);
|
unsigned Tmp4 = MakeReg(MVT::f64);
|
||||||
unsigned Tmp5 = MakeReg(MVT::f64);
|
unsigned Tmp5 = MakeReg(MVT::f64);
|
||||||
@ -1483,7 +1533,7 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
|||||||
case MVT::i1:
|
case MVT::i1:
|
||||||
Tmp2 = MakeReg(MVT::i64);
|
Tmp2 = MakeReg(MVT::i64);
|
||||||
BuildMI(BB, Alpha::ANDi, 2, Tmp2).addReg(Tmp1).addImm(1);
|
BuildMI(BB, Alpha::ANDi, 2, Tmp2).addReg(Tmp1).addImm(1);
|
||||||
BuildMI(BB, Alpha::SUBQ, 2, Result).addReg(Alpha::F31).addReg(Tmp2);
|
BuildMI(BB, Alpha::SUBQ, 2, Result).addReg(Alpha::R31).addReg(Tmp2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
@ -1609,6 +1659,8 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
|||||||
|
|
||||||
case ISD::CopyFromReg:
|
case ISD::CopyFromReg:
|
||||||
{
|
{
|
||||||
|
++count_ins;
|
||||||
|
|
||||||
// Make sure we generate both values.
|
// Make sure we generate both values.
|
||||||
if (Result != notIn)
|
if (Result != notIn)
|
||||||
ExprMap[N.getValue(1)] = notIn; // Generate the token
|
ExprMap[N.getValue(1)] = notIn; // Generate the token
|
||||||
@ -1626,10 +1678,10 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
|||||||
|
|
||||||
//Most of the plain arithmetic and logic share the same form, and the same
|
//Most of the plain arithmetic and logic share the same form, and the same
|
||||||
//constant immediate test
|
//constant immediate test
|
||||||
case ISD::OR:
|
case ISD::XOR:
|
||||||
//Match Not
|
//Match Not
|
||||||
if (N.getOperand(1).getOpcode() == ISD::Constant &&
|
if (N.getOperand(1).getOpcode() == ISD::Constant &&
|
||||||
cast<ConstantSDNode>(N.getOperand(1))->isAllOnesValue())
|
cast<ConstantSDNode>(N.getOperand(1))->getSignExtended() == -1)
|
||||||
{
|
{
|
||||||
Tmp1 = SelectExpr(N.getOperand(0));
|
Tmp1 = SelectExpr(N.getOperand(0));
|
||||||
BuildMI(BB, Alpha::ORNOT, 2, Result).addReg(Alpha::R31).addReg(Tmp1);
|
BuildMI(BB, Alpha::ORNOT, 2, Result).addReg(Alpha::R31).addReg(Tmp1);
|
||||||
@ -1637,11 +1689,11 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
|||||||
}
|
}
|
||||||
//Fall through
|
//Fall through
|
||||||
case ISD::AND:
|
case ISD::AND:
|
||||||
case ISD::XOR:
|
case ISD::OR:
|
||||||
//Check operand(0) == Not
|
//Check operand(0) == Not
|
||||||
if (N.getOperand(0).getOpcode() == ISD::OR &&
|
if (N.getOperand(0).getOpcode() == ISD::XOR &&
|
||||||
N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant &&
|
N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant &&
|
||||||
cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->isAllOnesValue())
|
cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->getSignExtended() == -1)
|
||||||
{
|
{
|
||||||
switch(opcode) {
|
switch(opcode) {
|
||||||
case ISD::AND: Opc = Alpha::BIC; break;
|
case ISD::AND: Opc = Alpha::BIC; break;
|
||||||
@ -1654,9 +1706,9 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
//Check operand(1) == Not
|
//Check operand(1) == Not
|
||||||
if (N.getOperand(1).getOpcode() == ISD::OR &&
|
if (N.getOperand(1).getOpcode() == ISD::XOR &&
|
||||||
N.getOperand(1).getOperand(1).getOpcode() == ISD::Constant &&
|
N.getOperand(1).getOperand(1).getOpcode() == ISD::Constant &&
|
||||||
cast<ConstantSDNode>(N.getOperand(1).getOperand(1))->isAllOnesValue())
|
cast<ConstantSDNode>(N.getOperand(1).getOperand(1))->getSignExtended() == -1)
|
||||||
{
|
{
|
||||||
switch(opcode) {
|
switch(opcode) {
|
||||||
case ISD::AND: Opc = Alpha::BIC; break;
|
case ISD::AND: Opc = Alpha::BIC; break;
|
||||||
@ -2044,6 +2096,7 @@ void ISel::Select(SDOperand N) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case ISD::ImplicitDef:
|
case ISD::ImplicitDef:
|
||||||
|
++count_ins;
|
||||||
Select(N.getOperand(0));
|
Select(N.getOperand(0));
|
||||||
BuildMI(BB, Alpha::IDEF, 0, cast<RegSDNode>(N)->getReg());
|
BuildMI(BB, Alpha::IDEF, 0, cast<RegSDNode>(N)->getReg());
|
||||||
return;
|
return;
|
||||||
@ -2060,6 +2113,7 @@ void ISel::Select(SDOperand N) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case ISD::CopyToReg:
|
case ISD::CopyToReg:
|
||||||
|
++count_outs;
|
||||||
Select(N.getOperand(0));
|
Select(N.getOperand(0));
|
||||||
Tmp1 = SelectExpr(N.getOperand(1));
|
Tmp1 = SelectExpr(N.getOperand(1));
|
||||||
Tmp2 = cast<RegSDNode>(N)->getReg();
|
Tmp2 = cast<RegSDNode>(N)->getReg();
|
||||||
@ -2074,6 +2128,7 @@ void ISel::Select(SDOperand N) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case ISD::RET:
|
case ISD::RET:
|
||||||
|
++count_outs;
|
||||||
switch (N.getNumOperands()) {
|
switch (N.getNumOperands()) {
|
||||||
default:
|
default:
|
||||||
std::cerr << N.getNumOperands() << "\n";
|
std::cerr << N.getNumOperands() << "\n";
|
||||||
@ -2137,6 +2192,7 @@ void ISel::Select(SDOperand N) {
|
|||||||
{
|
{
|
||||||
AlphaLowering.restoreGP(BB);
|
AlphaLowering.restoreGP(BB);
|
||||||
Opc = GetSymVersion(Opc);
|
Opc = GetSymVersion(Opc);
|
||||||
|
has_sym = true;
|
||||||
BuildMI(BB, Opc, 2).addReg(Tmp1).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
|
BuildMI(BB, Opc, 2).addReg(Tmp1).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
|
||||||
}
|
}
|
||||||
else if(Address.getOpcode() == ISD::FrameIndex)
|
else if(Address.getOpcode() == ISD::FrameIndex)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user