Eric Botcazou <ebotca...@adacore.com> writes: >> Also, the code is all goto-based, which makes it rather hard to step >> through. > > Do you mean the code in genrecog.c or the generated code in insn-recog.c?
The generated code. genrecog.c itself isn't bad. :-) >> PS. I've attached the new genrecog.c since the diff version is unreadable. > > Small request: you didn't change a single line of the head comment, yet the > size of the file is doubled. Could you add a sketch of the algorithm to the > head comment, e.g. by copy-and-pasting the above part of your message? OK. I'd left the head comment alone because it just described the interface, which hasn't changed. But I suppose past lack of commentary doesn't justify future lack of commentary. Here's what I added: At a high level, the algorithm used in this file is as follows: 1. Build up a decision tree for each routine, using the following approach to matching an rtx: - First determine the "shape" of the rtx, based on GET_CODE, XVECLEN and XINT. This phase examines SET_SRCs before SET_DESTs since SET_SRCs tend to be more distinctive. It examines other operands in numerical order, since the canonicalization rules prefer putting complex operands of commutative operators first. - Next check modes and predicates. This phase examines all operands in numerical order, even for SETs, since the mode of a SET_DEST is exact while the mode of a SET_SRC can be VOIDmode for constant integers. - Next check match_dups. - Finally check the C condition and (where appropriate) pnum_clobbers. 2. Try to optimize the tree by removing redundant tests, CSEing tests, folding tests together, etc. 3. Look for common subtrees and split them out into "pattern" routines. These common subtrees can be identical or they can differ in mode, code, or integer (usually an UNSPEC or UNSPEC_VOLATILE code). In the latter case the users of the pattern routine pass the appropriate mode, etc., as argument. For example, if two patterns contain: (plus:SI (match_operand:SI 1 "register_operand") (match_operand:SI 2 "register_operand")) we can split the associated matching code out into a subroutine. If a pattern contains: (minus:DI (match_operand:DI 1 "register_operand") (match_operand:DI 2 "register_operand")) then we can consider using the same matching routine for both the plus and minus expressions, passing PLUS and SImode in the former case and MINUS and DImode in the latter case. The main aim of this phase is to reduce the compile time of the insn-recog.c code and to reduce the amount of object code in insn-recog.o. 4. Split the matching trees into functions, trying to limit the size of each function to a sensible amount. Again, the main aim of this phase is to reduce the compile time of insn-recog.c. (It doesn't help with the size of insn-recog.o.) 5. Write out C++ code for each function. BTW, hope at least part of the doubling in size is due to more commentary in the code itself. > The old code contained a couple of DEBUG_FUNCTIONs but the new one doesn't. Yeah, but I don't know how useful they were. I had to debug the old code several times and never used them. I'd rather leave stuff like that to someone who wants it rather than try to write routines speculatively in the hope that someone would find them useful. Thanks, Richard