From f13120debba4d59da6b8ca432a22eaf64e338550 Mon Sep 17 00:00:00 2001 From: doe300 Date: Sun, 8 Jul 2018 14:38:44 +0200 Subject: [PATCH] Fixes bugs in sign-extension and selection-with-zero, speeds up integer division --- src/intermediate/TypeConversions.cpp | 9 ++++----- src/intrinsics/Operators.cpp | 17 +++++++---------- src/optimization/Combiner.cpp | 5 +++++ 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/intermediate/TypeConversions.cpp b/src/intermediate/TypeConversions.cpp index 74443176..c5472054 100644 --- a/src/intermediate/TypeConversions.cpp +++ b/src/intermediate/TypeConversions.cpp @@ -265,7 +265,7 @@ InstructionWalker intermediate::insertZeroExtension(InstructionWalker it, Method // do nothing, is just a move, since we truncate the 64-bit integers anyway it.emplace(new MoveOperation(dest, src, conditional, setFlags)); } - else if(dest.type.getScalarBitCount() == 32 && src.hasType(ValueType::REGISTER) && + else if(src.hasType(ValueType::REGISTER) && (has_flag(src.reg.file, RegisterFile::PHYSICAL_A) || has_flag(src.reg.file, RegisterFile::ACCUMULATOR)) && src.type.getScalarBitCount() == 8) { @@ -300,7 +300,7 @@ InstructionWalker intermediate::insertSignExtension(InstructionWalker it, Method // do nothing, is just a move, since we truncate the 64-bit integers anyway it.emplace(new MoveOperation(dest, src, conditional, setFlags)); } - else if(dest.type.getScalarBitCount() == 32 && src.hasType(ValueType::REGISTER) && + else if(src.hasType(ValueType::REGISTER) && (has_flag(src.reg.file, RegisterFile::PHYSICAL_A) || has_flag(src.reg.file, RegisterFile::ACCUMULATOR)) && src.type.getScalarBitCount() == 16) { @@ -312,15 +312,14 @@ InstructionWalker intermediate::insertSignExtension(InstructionWalker it, Method else { // out = asr(shl(in, bit_diff) bit_diff) - Value widthDiff( - Literal(static_cast(dest.type.getScalarBitCount() - src.type.getScalarBitCount())), TYPE_INT8); + // where bit_diff is the difference to full 32-bit + Value widthDiff(Literal(static_cast(32 - src.type.getScalarBitCount())), TYPE_INT8); if(!allowLiteral) { Value tmp = method.addNewLocal(TYPE_INT8, "%sext"); it.emplace(new LoadImmediate(tmp, widthDiff.literal)); it.nextInBlock(); - widthDiff = tmp; } diff --git a/src/intrinsics/Operators.cpp b/src/intrinsics/Operators.cpp index 8d445a5d..82117496 100644 --- a/src/intrinsics/Operators.cpp +++ b/src/intrinsics/Operators.cpp @@ -273,26 +273,23 @@ InstructionWalker intermediate::intrinsifyUnsignedIntegerDivision( it.nextInBlock(); remainder = newRemainder; // if R >= D then + // R = R >= D ? R - D : R <=> R = R - D >= 0 ? R - D : R <=> R = R - D < 0 ? R : R - D const Value tmp = method.addNewLocal(op.getOutput()->type, "%udiv.tmp"); - it.emplace(new Operation(OP_MAX, tmp, remainder, divisor)); + it.emplace(new Operation(OP_SUB, tmp, remainder, divisor, COND_ALWAYS, SetFlag::SET_FLAGS)); it.nextInBlock(); - it.emplace(new Operation(OP_XOR, NOP_REGISTER, tmp, remainder, COND_ALWAYS, SetFlag::SET_FLAGS)); - it.nextInBlock(); - // R := R - D newRemainder = method.addNewLocal(op.getOutput()->type, "%udiv.remainder"); - it.emplace(new Operation(OP_SUB, newRemainder, remainder, divisor, COND_ZERO_SET)); + it.emplace(new MoveOperation(newRemainder, tmp, COND_NEGATIVE_CLEAR)); it.nextInBlock(); - // else R(new) := R(old) - it.emplace(new MoveOperation(newRemainder, remainder, COND_ZERO_CLEAR)); + it.emplace(new MoveOperation(newRemainder, remainder, COND_NEGATIVE_SET)); it.nextInBlock(); remainder = newRemainder; // Q(i) := 1 Value newQuotient = method.addNewLocal(op.getOutput()->type, "%udiv.quotient"); - it.emplace(new Operation( - OP_OR, newQuotient, quotient, Value(Literal(static_cast(1) << i), TYPE_INT32), COND_ZERO_SET)); + it.emplace(new Operation(OP_OR, newQuotient, quotient, Value(Literal(static_cast(1) << i), TYPE_INT32), + COND_NEGATIVE_CLEAR)); it.nextInBlock(); // else Q(new) := Q(old) - it.emplace(new MoveOperation(newQuotient, quotient, COND_ZERO_CLEAR)); + it.emplace(new MoveOperation(newQuotient, quotient, COND_NEGATIVE_SET)); it.nextInBlock(); quotient = newQuotient; } diff --git a/src/optimization/Combiner.cpp b/src/optimization/Combiner.cpp index 90b39f62..eecab515 100644 --- a/src/optimization/Combiner.cpp +++ b/src/optimization/Combiner.cpp @@ -747,6 +747,11 @@ InstructionWalker optimizations::combineSelectionWithZero( if(it->conditional == COND_ALWAYS || nextIt->conditional == COND_ALWAYS || !it->conditional.isInversionOf(nextIt->conditional)) return it; + // For conditional moves, the source could be written conditionally + // TODO improve by removing the condition of the source and allow combining + // XXX actually would need to check if the condition is the same as the condition for the moves + if(it->hasConditionalExecution() || nextIt->hasConditionalExecution()) + return it; // we have two consecutive moves to the same value, without side-effects and inverted conditions. // additionally, one of the moves writes a zero-vale if(move->getSource().hasLiteral(INT_ZERO.literal) && !nextMove->getSource().hasLiteral(INT_ZERO.literal))