mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-08 21:32:39 +00:00
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
This commit is contained in:
parent
74fe063e90
commit
82e14db9a9
@ -97,6 +97,7 @@ unsigned SimpleSched::Emit(SDOperand Op) {
|
|||||||
while (NodeOperands &&
|
while (NodeOperands &&
|
||||||
Op.getOperand(NodeOperands-1).getValueType() == MVT::Flag)
|
Op.getOperand(NodeOperands-1).getValueType() == MVT::Flag)
|
||||||
--NodeOperands;
|
--NodeOperands;
|
||||||
|
|
||||||
if (NodeOperands && // Ignore chain if it exists.
|
if (NodeOperands && // Ignore chain if it exists.
|
||||||
Op.getOperand(NodeOperands-1).getValueType() == MVT::Other)
|
Op.getOperand(NodeOperands-1).getValueType() == MVT::Other)
|
||||||
--NodeOperands;
|
--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.
|
// 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()) {
|
if (Op.getOperand(i).isTargetOpcode()) {
|
||||||
// Note that this case is redundant with the final else block, but we
|
// 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
|
// include it because it is the most common and it makes the logic
|
||||||
// simpler here.
|
// simpler here.
|
||||||
unsigned R = Emit(Op.getOperand(i));
|
assert(Op.getOperand(i).getValueType() != MVT::Other &&
|
||||||
// Add an operand, unless this corresponds to a chain or flag node.
|
Op.getOperand(i).getValueType() != MVT::Flag &&
|
||||||
MVT::ValueType VT = Op.getOperand(i).getValueType();
|
"Chain and flag operands should occur at end of operand list!");
|
||||||
if (VT != MVT::Other && VT != MVT::Flag)
|
|
||||||
MI->addRegOperand(R, MachineOperand::Use);
|
MI->addRegOperand(Emit(Op.getOperand(i)), MachineOperand::Use);
|
||||||
} else if (ConstantSDNode *C =
|
} else if (ConstantSDNode *C =
|
||||||
dyn_cast<ConstantSDNode>(Op.getOperand(i))) {
|
dyn_cast<ConstantSDNode>(Op.getOperand(i))) {
|
||||||
MI->addZeroExtImm64Operand(C->getValue());
|
MI->addZeroExtImm64Operand(C->getValue());
|
||||||
@ -159,14 +166,26 @@ unsigned SimpleSched::Emit(SDOperand Op) {
|
|||||||
dyn_cast<ExternalSymbolSDNode>(Op.getOperand(i))) {
|
dyn_cast<ExternalSymbolSDNode>(Op.getOperand(i))) {
|
||||||
MI->addExternalSymbolOperand(ES->getSymbol(), false);
|
MI->addExternalSymbolOperand(ES->getSymbol(), false);
|
||||||
} else {
|
} else {
|
||||||
unsigned R = Emit(Op.getOperand(i));
|
assert(Op.getOperand(i).getValueType() != MVT::Other &&
|
||||||
// Add an operand, unless this corresponds to a chain or flag node.
|
Op.getOperand(i).getValueType() != MVT::Flag &&
|
||||||
MVT::ValueType VT = Op.getOperand(i).getValueType();
|
"Chain and flag operands should occur at end of operand list!");
|
||||||
if (VT != MVT::Other && VT != MVT::Flag)
|
MI->addRegOperand(Emit(Op.getOperand(i)), MachineOperand::Use);
|
||||||
MI->addRegOperand(R, 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.
|
// Now that we have emitted all operands, emit this instruction itself.
|
||||||
if ((II.Flags & M_USES_CUSTOM_DAG_SCHED_INSERTION) == 0) {
|
if ((II.Flags & M_USES_CUSTOM_DAG_SCHED_INSERTION) == 0) {
|
||||||
BB->insert(BB->end(), MI);
|
BB->insert(BB->end(), MI);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user