Bug 10675 – [Optimizer] optimize x >= a && x <= b and such to one comparison

Status
NEW
Severity
enhancement
Priority
P4
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-07-19T13:20:16Z
Last change time
2024-12-13T18:09:33Z
Assigned to
No Owner
Creator
Dmitry Olshansky
Moved to GitHub: dmd#18634 →

Attachments

IDFilenameSummaryContent-TypeSize
1236disasm.asmDisassembly of test casetext/plain6873

Comments

Comment #0 by dmitry.olsh — 2013-07-19T13:20:16Z
Currently DMD doesn't optimize interval-style conditions unlike GDC & LDC: x >= a && x <= b ---> //val size has to be big enough for the entire range of [0, b] unsigned val = x - a; val <= b - a The are multitude of alternatives of the above including if/else if chains and/or seuqnce of ifs with early return like: if(x < a) return false; if(x <= b return true; return false; See current (soon to be replaced) std.uni: https://github.com/D-Programming-Language/phobos/blob/master/std/uni.d#L563 Typical use-case are ASCII isAlpha/isDigit etc. functions heavily used in various lexers/scanners. See little "benchmark". Timings are dominated by loop overhead and memory access but a significant difference is observable non the less. import std.file; import std.stdio, std.datetime; //let compiler optimize if/else size_t process1(void[] buf) { size_t cnt = 0; foreach(i; 0..100) foreach(c; cast(ubyte[])buf) { if(c < 0xAA) { if(c < 'A') { } else if(c <= 'Z') cnt++; else if(c < 'a') { } else if(c <= 'z') cnt++; } } return cnt; } //do our job by hand size_t process2(void[] buf) { size_t cnt = 0; foreach(i; 0..100) foreach(c; cast(ubyte[])buf) { if(c < 0xAA) { //these x and y should be the smallest unsigned type to fit the range size_t x = c - 'A'; if(x <= 'Z'-'A') cnt++; else{ size_t y = c - 'a'; if(y <= 'z' - 'a') cnt++; } } } return cnt; } void main(string argv[]) { foreach(v; argv[1..$]){ StopWatch sw; sw.start(); version(compiler){ auto count = process1(read(v)); } else version(manual) auto count = process2(read(v)); else static assert(0); sw.stop(); writefln("%s %s ASCII alphabetic. [%d us]", v, count, sw.peek().usecs); } }
Comment #1 by dmitry.olsh — 2013-07-19T13:22:00Z
Created attachment 1236 Disassembly of test case Disassembly of 2 critical if-chainy functions.
Comment #2 by dmitry.olsh — 2013-07-19T13:23:23Z
Aye, and compiler flags used. First version: dmd -release -O -inline -noboundscheck -version=compiler if_else_opt.d Optimized by hand version: dmd -release -O -inline -noboundscheck -version=manual if_else_opt.d
Comment #3 by robert.schadek — 2024-12-13T18:09:33Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18634 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB