mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 16:29:21 +00:00
print warning when bit shifts are too large and result in 0. #83
This commit is contained in:
parent
3f07cad35d
commit
6830e15b4e
@ -20,7 +20,9 @@ import kotlin.math.pow
|
||||
|
||||
// TODO add more peephole expression optimizations? Investigate what optimizations binaryen has, also see https://egorbo.com/peephole-optimizations.html
|
||||
|
||||
class ExpressionSimplifier(private val program: Program, private val compTarget: ICompilationTarget) : AstWalker() {
|
||||
class ExpressionSimplifier(private val program: Program,
|
||||
private val errors: IErrorReporter,
|
||||
private val compTarget: ICompilationTarget) : AstWalker() {
|
||||
private val powersOfTwo = (1..16).map { (2.0).pow(it) }.toSet()
|
||||
private val negativePowersOfTwo = powersOfTwo.map { -it }.toSet()
|
||||
|
||||
@ -586,11 +588,13 @@ class ExpressionSimplifier(private val program: Program, private val compTarget:
|
||||
when (val targetDt = targetIDt.getOr(DataType.UNDEFINED)) {
|
||||
DataType.UBYTE, DataType.BYTE -> {
|
||||
if (amount >= 8) {
|
||||
errors.warn("shift always results in 0", expr.position)
|
||||
return NumericLiteral(targetDt, 0.0, expr.position)
|
||||
}
|
||||
}
|
||||
DataType.UWORD, DataType.WORD -> {
|
||||
if (amount >= 16) {
|
||||
errors.warn("shift always results in 0", expr.position)
|
||||
return NumericLiteral(targetDt, 0.0, expr.position)
|
||||
}
|
||||
else if(amount==8) {
|
||||
@ -625,6 +629,7 @@ class ExpressionSimplifier(private val program: Program, private val compTarget:
|
||||
when (idt.getOr(DataType.UNDEFINED)) {
|
||||
DataType.UBYTE -> {
|
||||
if (amount >= 8) {
|
||||
errors.warn("shift always results in 0", expr.position)
|
||||
return NumericLiteral.optimalInteger(0, expr.position)
|
||||
}
|
||||
}
|
||||
@ -636,6 +641,7 @@ class ExpressionSimplifier(private val program: Program, private val compTarget:
|
||||
}
|
||||
DataType.UWORD -> {
|
||||
if (amount >= 16) {
|
||||
errors.warn("shift always results in 0", expr.position)
|
||||
return NumericLiteral.optimalInteger(0, expr.position)
|
||||
}
|
||||
else if(amount==8) {
|
||||
|
@ -60,8 +60,8 @@ fun Program.inlineSubroutines(): Int {
|
||||
return inliner.applyModifications()
|
||||
}
|
||||
|
||||
fun Program.simplifyExpressions(target: ICompilationTarget) : Int {
|
||||
val opti = ExpressionSimplifier(this, target)
|
||||
fun Program.simplifyExpressions(errors: IErrorReporter, target: ICompilationTarget) : Int {
|
||||
val opti = ExpressionSimplifier(this, errors, target)
|
||||
opti.visit(this)
|
||||
return opti.applyModifications()
|
||||
}
|
||||
|
@ -361,7 +361,7 @@ private fun optimizeAst(program: Program, compilerOptions: CompilationOptions, e
|
||||
remover.applyModifications()
|
||||
while (true) {
|
||||
// keep optimizing expressions and statements until no more steps remain
|
||||
val optsDone1 = program.simplifyExpressions(compTarget)
|
||||
val optsDone1 = program.simplifyExpressions(errors, compTarget)
|
||||
val optsDone2 = program.splitBinaryExpressions(compilerOptions)
|
||||
val optsDone3 = program.optimizeStatements(errors, functions, compTarget)
|
||||
val optsDone4 = program.inlineSubroutines()
|
||||
|
@ -129,4 +129,18 @@ internal class BeforeAsmTypecastCleaner(val program: Program,
|
||||
}
|
||||
return noModifications
|
||||
}
|
||||
|
||||
override fun after(expr: BinaryExpression, parent: Node): Iterable<IAstModification> {
|
||||
if(expr.operator=="<<" || expr.operator==">>") {
|
||||
val shifts = expr.right.constValue(program)
|
||||
if(shifts!=null) {
|
||||
val dt = expr.left.inferType(program)
|
||||
if(dt.istype(DataType.UBYTE) && shifts.number>=8.0)
|
||||
errors.warn("shift always results in 0", expr.position)
|
||||
if(dt.istype(DataType.UWORD) && shifts.number>=16.0)
|
||||
errors.warn("shift always results in 0", expr.position)
|
||||
}
|
||||
}
|
||||
return noModifications
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user