Bugzilla – Bug 448
[asmwritergen] Factor common instruction patterns
Last modified: 2005-01-22 14:55:10
You need to log in before you can comment on or make changes to this bug.
The asmwriter generator currently generates a very straight-forward switch statement to print out the instructions for a target, something like this: bool PowerPCAsmPrinter::printInstruction(const MachineInstr *MI) { switch (MI->getOpcode()) { default: return false; case PPC::ADD: O << "add "; printOperand(MI, 0, MVT::i64); O << ", "; printOperand(MI, 1, MVT::i64); O << ", "; printOperand(MI, 2, MVT::i64); O << '\n'; break; case PPC::ADDC: O << "addc "; printOperand(MI, 0, MVT::i64); O << ", "; printOperand(MI, 1, MVT::i64); O << ", "; printOperand(MI, 2, MVT::i64); O << '\n'; break; case PPC::ADDE: O << "adde "; printOperand(MI, 0, MVT::i64); O << ", "; printOperand(MI, 1, MVT::i64); O << ", "; printOperand(MI, 2, MVT::i64); O << '\n'; break; ... Note that there is one case for each instruction. Unfortunately, compiling this function with GCC and optimizations sends GCC spinning and sucking up memory like crazy. To help with, it would be nice if the asmwriter generator factored code among instruction patterns that are identical except for small differences. In this case, it would be nice to generate: case PPC::ADD: case PPC::ADDC: case PPC::ADDE: O << OpcodeTable[MI->getOpcode()]; printOperand(MI, 0, MVT::i64); O << ", "; printOperand(MI, 1, MVT::i64); O << ", "; printOperand(MI, 2, MVT::i64); O << '\n'; break; Note that since most targets only have a few different flavors of instruction, this would dramatically reduce the amount of code in the switch statements. This would make the asmwriter generator faster (less to blow the icache) and not cause GCC to punish our release builds. -Chris
Here's another intermediate step that could be done and would help a lot as well. Because ALL instruction patterns start out with a string constant, we could emit the example code above, like this instead: bool PowerPCAsmPrinter::printInstruction(const MachineInstr *MI) { O << OpcodeTable[MI->getOpcode()]; switch (MI->getOpcode()) { default: return false; case PPC::ADD: printOperand(MI, 0, MVT::i64); O << ", "; printOperand(MI, 1, MVT::i64); O << ", "; printOperand(MI, 2, MVT::i64); O << '\n'; break; case PPC::ADDC: printOperand(MI, 0, MVT::i64); O << ", "; printOperand(MI, 1, MVT::i64); O << ", "; printOperand(MI, 2, MVT::i64); O << '\n'; break; case PPC::ADDE: printOperand(MI, 0, MVT::i64); O << ", "; printOperand(MI, 1, MVT::i64); O << ", "; printOperand(MI, 2, MVT::i64); O << '\n'; break; ... This isn't as big of a win as the full suggestion in the first comment, but it will help a LOT by itself and is much easier to implement. -Chris
This is now fixed: http://mail.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20050117/023573.html Building the PPC backend in release mode no longer causes GCC to hit swap for me. -Chris
This patch implements the second suggestion: http://mail.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20050117/023577.html This patch implements final cleanup/simplifications: http://mail.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20050117/023578.html -Chris