From 82e14db9a90413cc11fcf2ba27431346146aed75 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 29 Aug 2005 23:21:29 +0000 Subject: [PATCH] Add a hack to avoid some horrible code in some cases by always emitting token chains first. For this C function: int test() { int i; for (i = 0; i < 100000; ++i) foo(); } Instead of emitting this (condition before call) .LBB_test_1: ; no_exit addi r30, r30, 1 lis r2, 1 ori r2, r2, 34464 cmpw cr2, r30, r2 bl L_foo$stub bne cr2, .LBB_test_1 ; no_exit Emit this: .LBB_test_1: ; no_exit bl L_foo$stub addi r30, r30, 1 lis r2, 1 ori r2, r2, 34464 cmpw cr0, r30, r2 bne cr0, .LBB_test_1 ; no_exit Which makes it so we don't have to save/restore cr2 in the prolog/epilog of the function. This also makes the code much more similar to what the pattern isel produces. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23135 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/ScheduleDAG.cpp | 43 +++++++++++++++++------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp index 723daed42f0..af751edcbf5 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp @@ -97,6 +97,7 @@ unsigned SimpleSched::Emit(SDOperand Op) { while (NodeOperands && Op.getOperand(NodeOperands-1).getValueType() == MVT::Flag) --NodeOperands; + if (NodeOperands && // Ignore chain if it exists. Op.getOperand(NodeOperands-1).getValueType() == MVT::Other) --NodeOperands; @@ -125,18 +126,24 @@ unsigned SimpleSched::Emit(SDOperand Op) { } } - // Emit all of the operands of this instruction, adding them to the + // If there is a token chain operand, emit it first, as a hack to get avoid + // really bad cases. + if (Op.getNumOperands() > NodeOperands && + Op.getOperand(NodeOperands).getValueType() == MVT::Other) + Emit(Op.getOperand(NodeOperands)); + + // Emit all of the actual operands of this instruction, adding them to the // instruction as appropriate. - for (unsigned i = 0, e = Op.getNumOperands(); i != e; ++i) { + for (unsigned i = 0; i != NodeOperands; ++i) { if (Op.getOperand(i).isTargetOpcode()) { // Note that this case is redundant with the final else block, but we // include it because it is the most common and it makes the logic // simpler here. - unsigned R = Emit(Op.getOperand(i)); - // Add an operand, unless this corresponds to a chain or flag node. - MVT::ValueType VT = Op.getOperand(i).getValueType(); - if (VT != MVT::Other && VT != MVT::Flag) - MI->addRegOperand(R, MachineOperand::Use); + assert(Op.getOperand(i).getValueType() != MVT::Other && + Op.getOperand(i).getValueType() != MVT::Flag && + "Chain and flag operands should occur at end of operand list!"); + + MI->addRegOperand(Emit(Op.getOperand(i)), MachineOperand::Use); } else if (ConstantSDNode *C = dyn_cast(Op.getOperand(i))) { MI->addZeroExtImm64Operand(C->getValue()); @@ -159,14 +166,26 @@ unsigned SimpleSched::Emit(SDOperand Op) { dyn_cast(Op.getOperand(i))) { MI->addExternalSymbolOperand(ES->getSymbol(), false); } else { - unsigned R = Emit(Op.getOperand(i)); - // Add an operand, unless this corresponds to a chain or flag node. - MVT::ValueType VT = Op.getOperand(i).getValueType(); - if (VT != MVT::Other && VT != MVT::Flag) - MI->addRegOperand(R, MachineOperand::Use); + assert(Op.getOperand(i).getValueType() != MVT::Other && + Op.getOperand(i).getValueType() != MVT::Flag && + "Chain and flag operands should occur at end of operand list!"); + MI->addRegOperand(Emit(Op.getOperand(i)), MachineOperand::Use); } } + // Finally, if this node has any flag operands, we *must* emit them last, to + // avoid emitting operations that might clobber the flags. + if (Op.getNumOperands() > NodeOperands) { + unsigned i = NodeOperands; + if (Op.getOperand(i).getValueType() == MVT::Other) + ++i; // the chain is already selected. + for (; i != Op.getNumOperands(); ++i) { + assert(Op.getOperand(i).getValueType() == MVT::Flag && + "Must be flag operands!"); + Emit(Op.getOperand(i)); + } + } + // Now that we have emitted all operands, emit this instruction itself. if ((II.Flags & M_USES_CUSTOM_DAG_SCHED_INSERTION) == 0) { BB->insert(BB->end(), MI); -- 2.34.1