mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-01 00:33:09 +00:00
Remove BRTWOWAY*
Make the PPC backend not dependent on BRTWOWAY_CC and make the branch selector smarter about the code it generates, fixing a case in the readme. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26814 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e261c474ca
commit
81e8097377
@ -302,25 +302,12 @@ namespace ISD {
|
||||
// to if the condition is true.
|
||||
BRCOND,
|
||||
|
||||
// BRCONDTWOWAY - Two-way conditional branch. The first operand is the
|
||||
// chain, the second is the condition, the third is the block to branch to
|
||||
// if true, and the forth is the block to branch to if false. Targets
|
||||
// usually do not implement this, preferring to have legalize demote the
|
||||
// operation to BRCOND/BR pairs when necessary.
|
||||
BRCONDTWOWAY,
|
||||
|
||||
// BR_CC - Conditional branch. The behavior is like that of SELECT_CC, in
|
||||
// that the condition is represented as condition code, and two nodes to
|
||||
// compare, rather than as a combined SetCC node. The operands in order are
|
||||
// chain, cc, lhs, rhs, block to branch to if condition is true.
|
||||
BR_CC,
|
||||
|
||||
// BRTWOWAY_CC - Two-way conditional branch. The operands in order are
|
||||
// chain, cc, lhs, rhs, block to branch to if condition is true, block to
|
||||
// branch to if condition is false. Targets usually do not implement this,
|
||||
// preferring to have legalize demote the operation to BRCOND/BR pairs.
|
||||
BRTWOWAY_CC,
|
||||
|
||||
// RET - Return from function. The first operand is the chain,
|
||||
// and any subsequent operands are the return values for the
|
||||
// function. This operation can have variable number of operands.
|
||||
|
@ -206,9 +206,7 @@ namespace {
|
||||
SDOperand visitFNEG(SDNode *N);
|
||||
SDOperand visitFABS(SDNode *N);
|
||||
SDOperand visitBRCOND(SDNode *N);
|
||||
SDOperand visitBRCONDTWOWAY(SDNode *N);
|
||||
SDOperand visitBR_CC(SDNode *N);
|
||||
SDOperand visitBRTWOWAY_CC(SDNode *N);
|
||||
SDOperand visitLOAD(SDNode *N);
|
||||
SDOperand visitSTORE(SDNode *N);
|
||||
|
||||
@ -639,9 +637,7 @@ SDOperand DAGCombiner::visit(SDNode *N) {
|
||||
case ISD::FNEG: return visitFNEG(N);
|
||||
case ISD::FABS: return visitFABS(N);
|
||||
case ISD::BRCOND: return visitBRCOND(N);
|
||||
case ISD::BRCONDTWOWAY: return visitBRCONDTWOWAY(N);
|
||||
case ISD::BR_CC: return visitBR_CC(N);
|
||||
case ISD::BRTWOWAY_CC: return visitBRTWOWAY_CC(N);
|
||||
case ISD::LOAD: return visitLOAD(N);
|
||||
case ISD::STORE: return visitSTORE(N);
|
||||
}
|
||||
@ -2219,35 +2215,6 @@ SDOperand DAGCombiner::visitBRCOND(SDNode *N) {
|
||||
return SDOperand();
|
||||
}
|
||||
|
||||
SDOperand DAGCombiner::visitBRCONDTWOWAY(SDNode *N) {
|
||||
SDOperand Chain = N->getOperand(0);
|
||||
SDOperand N1 = N->getOperand(1);
|
||||
SDOperand N2 = N->getOperand(2);
|
||||
SDOperand N3 = N->getOperand(3);
|
||||
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
|
||||
|
||||
// unconditional branch to true mbb
|
||||
if (N1C && N1C->getValue() == 1)
|
||||
return DAG.getNode(ISD::BR, MVT::Other, Chain, N2);
|
||||
// unconditional branch to false mbb
|
||||
if (N1C && N1C->isNullValue())
|
||||
return DAG.getNode(ISD::BR, MVT::Other, Chain, N3);
|
||||
// fold a brcondtwoway with a setcc condition into a BRTWOWAY_CC node if
|
||||
// BRTWOWAY_CC is legal on the target.
|
||||
if (N1.getOpcode() == ISD::SETCC &&
|
||||
TLI.isOperationLegal(ISD::BRTWOWAY_CC, MVT::Other)) {
|
||||
std::vector<SDOperand> Ops;
|
||||
Ops.push_back(Chain);
|
||||
Ops.push_back(N1.getOperand(2));
|
||||
Ops.push_back(N1.getOperand(0));
|
||||
Ops.push_back(N1.getOperand(1));
|
||||
Ops.push_back(N2);
|
||||
Ops.push_back(N3);
|
||||
return DAG.getNode(ISD::BRTWOWAY_CC, MVT::Other, Ops);
|
||||
}
|
||||
return SDOperand();
|
||||
}
|
||||
|
||||
// Operand List for BR_CC: Chain, CondCC, CondLHS, CondRHS, DestBB.
|
||||
//
|
||||
SDOperand DAGCombiner::visitBR_CC(SDNode *N) {
|
||||
@ -2273,41 +2240,6 @@ SDOperand DAGCombiner::visitBR_CC(SDNode *N) {
|
||||
return SDOperand();
|
||||
}
|
||||
|
||||
SDOperand DAGCombiner::visitBRTWOWAY_CC(SDNode *N) {
|
||||
SDOperand Chain = N->getOperand(0);
|
||||
SDOperand CCN = N->getOperand(1);
|
||||
SDOperand LHS = N->getOperand(2);
|
||||
SDOperand RHS = N->getOperand(3);
|
||||
SDOperand N4 = N->getOperand(4);
|
||||
SDOperand N5 = N->getOperand(5);
|
||||
|
||||
SDOperand SCC = SimplifySetCC(TLI.getSetCCResultTy(), LHS, RHS,
|
||||
cast<CondCodeSDNode>(CCN)->get(), false);
|
||||
ConstantSDNode *SCCC = dyn_cast_or_null<ConstantSDNode>(SCC.Val);
|
||||
|
||||
// fold select_cc lhs, rhs, x, x, cc -> x
|
||||
if (N4 == N5)
|
||||
return DAG.getNode(ISD::BR, MVT::Other, Chain, N4);
|
||||
// fold select_cc true, x, y -> x
|
||||
if (SCCC && SCCC->getValue())
|
||||
return DAG.getNode(ISD::BR, MVT::Other, Chain, N4);
|
||||
// fold select_cc false, x, y -> y
|
||||
if (SCCC && SCCC->isNullValue())
|
||||
return DAG.getNode(ISD::BR, MVT::Other, Chain, N5);
|
||||
// fold to a simpler setcc
|
||||
if (SCC.Val && SCC.getOpcode() == ISD::SETCC) {
|
||||
std::vector<SDOperand> Ops;
|
||||
Ops.push_back(Chain);
|
||||
Ops.push_back(SCC.getOperand(2));
|
||||
Ops.push_back(SCC.getOperand(0));
|
||||
Ops.push_back(SCC.getOperand(1));
|
||||
Ops.push_back(N4);
|
||||
Ops.push_back(N5);
|
||||
return DAG.getNode(ISD::BRTWOWAY_CC, MVT::Other, Ops);
|
||||
}
|
||||
return SDOperand();
|
||||
}
|
||||
|
||||
SDOperand DAGCombiner::visitLOAD(SDNode *N) {
|
||||
SDOperand Chain = N->getOperand(0);
|
||||
SDOperand Ptr = N->getOperand(1);
|
||||
|
@ -945,100 +945,6 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ISD::BRCONDTWOWAY:
|
||||
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
|
||||
switch (getTypeAction(Node->getOperand(1).getValueType())) {
|
||||
case Expand: assert(0 && "It's impossible to expand bools");
|
||||
case Legal:
|
||||
Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the condition.
|
||||
break;
|
||||
case Promote:
|
||||
Tmp2 = PromoteOp(Node->getOperand(1)); // Promote the condition.
|
||||
break;
|
||||
}
|
||||
|
||||
// If this target does not support BRCONDTWOWAY, lower it to a BRCOND/BR
|
||||
// pair.
|
||||
switch (TLI.getOperationAction(ISD::BRCONDTWOWAY, MVT::Other)) {
|
||||
case TargetLowering::Promote:
|
||||
default: assert(0 && "This action is not supported yet!");
|
||||
case TargetLowering::Legal:
|
||||
Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2),
|
||||
Node->getOperand(3));
|
||||
break;
|
||||
case TargetLowering::Expand:
|
||||
// If BRTWOWAY_CC is legal for this target, then simply expand this node
|
||||
// to that. Otherwise, skip BRTWOWAY_CC and expand directly to a
|
||||
// BRCOND/BR pair.
|
||||
if (TLI.isOperationLegal(ISD::BRTWOWAY_CC, MVT::Other)) {
|
||||
if (Tmp2.getOpcode() == ISD::SETCC) {
|
||||
Tmp3 = Tmp2.getOperand(0);
|
||||
Tmp4 = Tmp2.getOperand(1);
|
||||
Tmp2 = Tmp2.getOperand(2);
|
||||
} else {
|
||||
Tmp3 = Tmp2;
|
||||
Tmp4 = DAG.getConstant(0, Tmp2.getValueType());
|
||||
Tmp2 = DAG.getCondCode(ISD::SETNE);
|
||||
}
|
||||
std::vector<SDOperand> Ops;
|
||||
Ops.push_back(Tmp1);
|
||||
Ops.push_back(Tmp2);
|
||||
Ops.push_back(Tmp3);
|
||||
Ops.push_back(Tmp4);
|
||||
Ops.push_back(Node->getOperand(2));
|
||||
Ops.push_back(Node->getOperand(3));
|
||||
Result = DAG.getNode(ISD::BRTWOWAY_CC, MVT::Other, Ops);
|
||||
} else {
|
||||
Result = DAG.getNode(ISD::BRCOND, MVT::Other, Tmp1, Tmp2,
|
||||
Node->getOperand(2));
|
||||
Result = DAG.getNode(ISD::BR, MVT::Other, Result, Node->getOperand(3));
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ISD::BRTWOWAY_CC: {
|
||||
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
|
||||
// Ensure that libcalls are emitted before a branch.
|
||||
Tmp1 = DAG.getNode(ISD::TokenFactor, MVT::Other, Tmp1, LastCALLSEQ_END);
|
||||
Tmp1 = LegalizeOp(Tmp1);
|
||||
LastCALLSEQ_END = DAG.getEntryNode();
|
||||
|
||||
Tmp2 = Node->getOperand(2); // LHS
|
||||
Tmp3 = Node->getOperand(3); // RHS
|
||||
Tmp4 = Node->getOperand(1); // CC
|
||||
|
||||
LegalizeSetCCOperands(Tmp2, Tmp3, Tmp4);
|
||||
|
||||
// If we didn't get both a LHS and RHS back from LegalizeSetCCOperands,
|
||||
// the LHS is a legal SETCC itself. In this case, we need to compare
|
||||
// the result against zero to select between true and false values.
|
||||
if (Tmp3.Val == 0) {
|
||||
Tmp3 = DAG.getConstant(0, Tmp2.getValueType());
|
||||
Tmp4 = DAG.getCondCode(ISD::SETNE);
|
||||
}
|
||||
std::vector<SDOperand> Ops;
|
||||
Ops.push_back(Tmp1);
|
||||
Ops.push_back(Tmp4);
|
||||
Ops.push_back(Tmp2);
|
||||
Ops.push_back(Tmp3);
|
||||
Ops.push_back(Node->getOperand(4));
|
||||
Ops.push_back(Node->getOperand(5));
|
||||
Result = DAG.UpdateNodeOperands(Result, Ops);
|
||||
|
||||
// Everything is legal, see if we should expand this op or something.
|
||||
switch (TLI.getOperationAction(ISD::BRTWOWAY_CC, MVT::Other)) {
|
||||
default: assert(0 && "This action is not supported yet!");
|
||||
case TargetLowering::Legal: break;
|
||||
case TargetLowering::Expand:
|
||||
Result = DAG.getNode(ISD::BRCOND, MVT::Other, Tmp1,
|
||||
DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), Tmp2,
|
||||
Tmp3, Tmp4),
|
||||
Result.getOperand(4));
|
||||
Result = DAG.getNode(ISD::BR, MVT::Other, Result, Result.getOperand(5));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ISD::LOAD: {
|
||||
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
|
||||
Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer.
|
||||
|
@ -1486,18 +1486,6 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
|
||||
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(Ops[1].Val);
|
||||
switch (Opcode) {
|
||||
default: break;
|
||||
case ISD::BRCONDTWOWAY:
|
||||
if (N1C)
|
||||
if (N1C->getValue()) // Unconditional branch to true dest.
|
||||
return getNode(ISD::BR, MVT::Other, Ops[0], Ops[2]);
|
||||
else // Unconditional branch to false dest.
|
||||
return getNode(ISD::BR, MVT::Other, Ops[0], Ops[3]);
|
||||
break;
|
||||
case ISD::BRTWOWAY_CC:
|
||||
assert(Ops.size() == 6 && "BRTWOWAY_CC takes 6 operands!");
|
||||
assert(Ops[2].getValueType() == Ops[3].getValueType() &&
|
||||
"LHS and RHS of comparison must have same type!");
|
||||
break;
|
||||
case ISD::TRUNCSTORE: {
|
||||
assert(Ops.size() == 5 && "TRUNCSTORE takes 5 operands!");
|
||||
MVT::ValueType EVT = cast<VTSDNode>(Ops[4])->getVT();
|
||||
@ -2692,9 +2680,7 @@ const char *SDNode::getOperationName(const SelectionDAG *G) const {
|
||||
// Control flow instructions
|
||||
case ISD::BR: return "br";
|
||||
case ISD::BRCOND: return "brcond";
|
||||
case ISD::BRCONDTWOWAY: return "brcondtwoway";
|
||||
case ISD::BR_CC: return "br_cc";
|
||||
case ISD::BRTWOWAY_CC: return "brtwoway_cc";
|
||||
case ISD::BR_CC: return "br_cc";
|
||||
case ISD::RET: return "ret";
|
||||
case ISD::CALLSEQ_START: return "callseq_start";
|
||||
case ISD::CALLSEQ_END: return "callseq_end";
|
||||
|
@ -691,10 +691,10 @@ void SelectionDAGLowering::visitBr(BranchInst &I) {
|
||||
SDOperand True = DAG.getConstant(1, Cond.getValueType());
|
||||
Cond = DAG.getNode(ISD::XOR, Cond.getValueType(), Cond, True);
|
||||
}
|
||||
Ops.push_back(Cond);
|
||||
Ops.push_back(DAG.getBasicBlock(Succ0MBB));
|
||||
Ops.push_back(DAG.getBasicBlock(Succ1MBB));
|
||||
DAG.setRoot(DAG.getNode(ISD::BRCONDTWOWAY, MVT::Other, Ops));
|
||||
SDOperand True = DAG.getNode(ISD::BRCOND, MVT::Other, getRoot(), Cond,
|
||||
DAG.getBasicBlock(Succ0MBB));
|
||||
DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, True,
|
||||
DAG.getBasicBlock(Succ1MBB)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,8 +48,6 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM)
|
||||
addRegisterClass(MVT::f64, Alpha::F8RCRegisterClass);
|
||||
addRegisterClass(MVT::f32, Alpha::F4RCRegisterClass);
|
||||
|
||||
setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand);
|
||||
setOperationAction(ISD::BRTWOWAY_CC, MVT::Other, Expand);
|
||||
setOperationAction(ISD::BR_CC, MVT::Other, Expand);
|
||||
setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
|
||||
|
||||
|
@ -36,8 +36,6 @@ IA64TargetLowering::IA64TargetLowering(TargetMachine &TM)
|
||||
addRegisterClass(MVT::i1, IA64::PRRegisterClass);
|
||||
|
||||
setOperationAction(ISD::BR_CC , MVT::Other, Expand);
|
||||
setOperationAction(ISD::BRCONDTWOWAY , MVT::Other, Expand);
|
||||
setOperationAction(ISD::BRTWOWAY_CC , MVT::Other, Expand);
|
||||
setOperationAction(ISD::FP_ROUND_INREG , MVT::f32 , Expand);
|
||||
|
||||
// ia64 uses SELECT not SELECT_CC
|
||||
|
@ -48,10 +48,10 @@ FunctionPass *llvm::createPPCBranchSelectionPass() {
|
||||
static unsigned getNumBytesForInstruction(MachineInstr *MI) {
|
||||
switch (MI->getOpcode()) {
|
||||
case PPC::COND_BRANCH:
|
||||
// while this will be 4 most of the time, if we emit 12 it is just a
|
||||
// while this will be 4 most of the time, if we emit 8 it is just a
|
||||
// minor pessimization that saves us from having to worry about
|
||||
// keeping the offsets up to date later when we emit long branch glue.
|
||||
return 12;
|
||||
return 8;
|
||||
case PPC::IMPLICIT_DEF_GPR: // no asm emitted
|
||||
case PPC::IMPLICIT_DEF_F4: // no asm emitted
|
||||
case PPC::IMPLICIT_DEF_F8: // no asm emitted
|
||||
@ -102,7 +102,6 @@ bool PPCBSel::runOnMachineFunction(MachineFunction &Fn) {
|
||||
// long branch:
|
||||
// bInverseCC $PC+8
|
||||
// b .L_TARGET_MBB
|
||||
// b .L_FALLTHROUGH_MBB
|
||||
for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
|
||||
++MFI) {
|
||||
MachineBasicBlock *MBB = MFI;
|
||||
@ -123,8 +122,6 @@ bool PPCBSel::runOnMachineFunction(MachineFunction &Fn) {
|
||||
// 3. fallthrough MBB
|
||||
MachineBasicBlock *trueMBB =
|
||||
MBBI->getOperand(2).getMachineBasicBlock();
|
||||
MachineBasicBlock *falseMBB =
|
||||
MBBI->getOperand(3).getMachineBasicBlock();
|
||||
|
||||
int Displacement = OffsetMap[trueMBB] - ByteCount;
|
||||
unsigned Opcode = MBBI->getOperand(1).getImmedValue();
|
||||
@ -136,7 +133,6 @@ bool PPCBSel::runOnMachineFunction(MachineFunction &Fn) {
|
||||
} else {
|
||||
BuildMI(*MBB, MBBJ, Inverted, 2).addReg(CRReg).addSImm(8);
|
||||
BuildMI(*MBB, MBBJ, PPC::B, 1).addMBB(trueMBB);
|
||||
BuildMI(*MBB, MBBJ, PPC::B, 1).addMBB(falseMBB);
|
||||
}
|
||||
|
||||
// Erase the psuedo COND_BRANCH instruction, and then back up the
|
||||
|
@ -1105,44 +1105,14 @@ void PPCDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
||||
N2, N3, getI32Imm(BROpc));
|
||||
return;
|
||||
}
|
||||
case ISD::BR_CC:
|
||||
case ISD::BRTWOWAY_CC: {
|
||||
case ISD::BR_CC: {
|
||||
SDOperand Chain;
|
||||
Select(Chain, N->getOperand(0));
|
||||
MachineBasicBlock *Dest =
|
||||
cast<BasicBlockSDNode>(N->getOperand(4))->getBasicBlock();
|
||||
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(1))->get();
|
||||
SDOperand CondCode = SelectCC(N->getOperand(2), N->getOperand(3), CC);
|
||||
|
||||
// If this is a two way branch, then grab the fallthrough basic block
|
||||
// argument and build a PowerPC branch pseudo-op, suitable for long branch
|
||||
// conversion if necessary by the branch selection pass. Otherwise, emit a
|
||||
// standard conditional branch.
|
||||
if (N->getOpcode() == ISD::BRTWOWAY_CC) {
|
||||
SDOperand CondTrueBlock = N->getOperand(4);
|
||||
SDOperand CondFalseBlock = N->getOperand(5);
|
||||
unsigned Opc = getBCCForSetCC(CC);
|
||||
SDOperand CB =
|
||||
SDOperand(CurDAG->getTargetNode(PPC::COND_BRANCH, MVT::Other,
|
||||
CondCode, getI32Imm(Opc),
|
||||
CondTrueBlock, CondFalseBlock,
|
||||
Chain), 0);
|
||||
Result = CurDAG->SelectNodeTo(N, PPC::B, MVT::Other, CondFalseBlock, CB);
|
||||
} else {
|
||||
// Iterate to the next basic block
|
||||
ilist<MachineBasicBlock>::iterator It = BB;
|
||||
++It;
|
||||
|
||||
// If the fallthrough path is off the end of the function, which would be
|
||||
// undefined behavior, set it to be the same as the current block because
|
||||
// we have nothing better to set it to, and leaving it alone will cause
|
||||
// the PowerPC Branch Selection pass to crash.
|
||||
if (It == BB->getParent()->end()) It = Dest;
|
||||
Result = CurDAG->SelectNodeTo(N, PPC::COND_BRANCH, MVT::Other, CondCode,
|
||||
getI32Imm(getBCCForSetCC(CC)),
|
||||
N->getOperand(4), CurDAG->getBasicBlock(It),
|
||||
Chain);
|
||||
}
|
||||
Result = CurDAG->SelectNodeTo(N, PPC::COND_BRANCH, MVT::Other,
|
||||
CondCode, getI32Imm(getBCCForSetCC(CC)),
|
||||
N->getOperand(4), Chain);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -94,9 +94,8 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM)
|
||||
// PowerPC wants to optimize integer setcc a bit
|
||||
setOperationAction(ISD::SETCC, MVT::i32, Custom);
|
||||
|
||||
// PowerPC does not have BRCOND* which requires SetCC
|
||||
setOperationAction(ISD::BRCOND, MVT::Other, Expand);
|
||||
setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand);
|
||||
// PowerPC does not have BRCOND which requires SetCC
|
||||
setOperationAction(ISD::BRCOND, MVT::Other, Expand);
|
||||
|
||||
// PowerPC turns FP_TO_SINT into FCTIWZ and some load/stores.
|
||||
setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
|
||||
|
@ -245,8 +245,7 @@ let Defs = [LR] in
|
||||
|
||||
let isBranch = 1, isTerminator = 1, hasCtrlDep = 1,
|
||||
noResults = 1, PPC970_Unit = 7 in {
|
||||
def COND_BRANCH : Pseudo<(ops CRRC:$crS, u16imm:$opc,
|
||||
target:$true, target:$false),
|
||||
def COND_BRANCH : Pseudo<(ops CRRC:$crS, u16imm:$opc, target:$true),
|
||||
"; COND_BRANCH", []>;
|
||||
def B : IForm<18, 0, 0, (ops target:$dst),
|
||||
"b $dst", BrB,
|
||||
|
@ -10,41 +10,8 @@ still a codesize win.
|
||||
|
||||
===-------------------------------------------------------------------------===
|
||||
|
||||
Should hint to the branch select pass that it doesn't need to print the second
|
||||
unconditional branch, so we don't end up with things like:
|
||||
b .LBBl42__2E_expand_function_8_674 ; loopentry.24
|
||||
b .LBBl42__2E_expand_function_8_42 ; NewDefault
|
||||
b .LBBl42__2E_expand_function_8_42 ; NewDefault
|
||||
|
||||
This occurs in SPASS.
|
||||
|
||||
The power of diet coke came up with a solution to this today:
|
||||
|
||||
We know the only two cases that can happen here are either:
|
||||
a) we have a conditional branch followed by a fallthrough to the next BB
|
||||
b) we have a conditional branch followed by an unconditional branch
|
||||
|
||||
We also invented the BRTWOWAY node to model (b).
|
||||
|
||||
Currently, these are modeled by the PPC_BRCOND node which is a 12-byte pseudo
|
||||
that codegens to
|
||||
bccinv false
|
||||
true:
|
||||
b truebb
|
||||
false:
|
||||
b falsebb
|
||||
|
||||
However, realizing that for (a), we can bccinv directly to the fallthrough
|
||||
block, and for (b) we will already have another unconditional branch after
|
||||
the conditional branch (see SPASS case above), then we know that we don't need
|
||||
BRTWOWAY at all, and can just codegen PPC_BRCOND as
|
||||
|
||||
bccinv +8
|
||||
b truebb
|
||||
|
||||
This will also allow us to selectively not run the ppc branch selector, by just
|
||||
selecting PPC_BRCOND pseudo directly to the correct conditional branch
|
||||
instruction for small functions.
|
||||
Teach the .td file to pattern match PPC::BR_COND to appropriate bc variant, so
|
||||
we don't have to always run the branch selector for small functions.
|
||||
|
||||
===-------------------------------------------------------------------------===
|
||||
|
||||
|
@ -17,7 +17,11 @@ We currently compile this into a memcpy from a static array into 'm', then
|
||||
a bunch of loads from m. It would be better to avoid the memcpy and just do
|
||||
loads from the static array.
|
||||
|
||||
===-------------------------------------------------------------------------===
|
||||
//===---------------------------------------------------------------------===//
|
||||
|
||||
Make the PPC branch selector target independant
|
||||
|
||||
//===---------------------------------------------------------------------===//
|
||||
|
||||
Get the C front-end to expand hypot(x,y) -> llvm.sqrt(x*x+y*y) when errno and
|
||||
precision don't matter (ffastmath). Misc/mandel will like this. :)
|
||||
|
@ -166,8 +166,6 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
|
||||
|
||||
// Sparc doesn't have BRCOND either, it has BR_CC.
|
||||
setOperationAction(ISD::BRCOND, MVT::Other, Expand);
|
||||
setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand);
|
||||
setOperationAction(ISD::BRTWOWAY_CC, MVT::Other, Expand);
|
||||
setOperationAction(ISD::BR_CC, MVT::i32, Custom);
|
||||
setOperationAction(ISD::BR_CC, MVT::f32, Custom);
|
||||
setOperationAction(ISD::BR_CC, MVT::f64, Custom);
|
||||
|
@ -125,8 +125,6 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::BIT_CONVERT , MVT::i32 , Expand);
|
||||
|
||||
setOperationAction(ISD::BRCOND , MVT::Other, Custom);
|
||||
setOperationAction(ISD::BRCONDTWOWAY , MVT::Other, Expand);
|
||||
setOperationAction(ISD::BRTWOWAY_CC , MVT::Other, Expand);
|
||||
setOperationAction(ISD::BR_CC , MVT::Other, Expand);
|
||||
setOperationAction(ISD::SELECT_CC , MVT::Other, Expand);
|
||||
setOperationAction(ISD::MEMMOVE , MVT::Other, Expand);
|
||||
|
Loading…
Reference in New Issue
Block a user