Fix generation of .reginfo and .Mips.options.
We now determine the register usage of the module and set .reginfo and .Mips.options accordingly. We do this by checking each register operand of every instruction before emitting them.
Details
- Reviewers
dsanders
Diff Detail
Event Timeline
My general comments are that MipsRegInfo should own all methods related to updating and emitting the section and that MipsRegInfo instances should belong to MipsTargetELFStreamer (or MipsTargetStreamer) instead of MipsMCCodeEmitter.
The reason for this is to make it possible to support the other .MIPS.options records easily in the future by having a MipsTargetELFStreamer::EmitOptionRecord(MipsOptionRecord&) method. This should also sort out the issue with 'mutable'.
I foresee ending up at something like this:
class MipsOptionRecord { public: void EmitMipsOptionRecord(MipsTargetStreamer &Streamer) = 0; } class MipsRegInfo : MipsOptionRecord { public: void SetPhysRegUsed(unsigned Reg); // Other arguments include anything needed to iterate over subregs. void EmitRegInfoRecord(MipsTargetStreamer &Streamer); // For the legacy .reginfo section void EmitMipsOptionRecord(MipsTargetStreamer &Streamer); } // Other MipsRegInfo subclasses class MipsTargetStreamer { ... std::vector<MipsOptionRecord> MipsOptionRecords; ... void EmitMipsOptionRecords(void); }
To be clear, you don't need to implement all of this up front but it would be good to make migrating to this simple.
This will make it difficult to hook MCCodeEmitter::EncodeInstruction(), but overriding MCObjectStreamer::EmitInstToFragment() looks like a suitable alternative.
lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | ||
---|---|---|
224–256 | Instead of listing every register class, you could define an unallocatable register class that contains all the relevant registers and test whether the register is a member of those classes. Also, consider using MCSubRegIterator(Op.getReg(), Ctx.getRegisterInfo(), true) so you don't need to treat FR=0 mode as a special case. It would be nice to have access to llvm::MachineRegisterInfo::isPhysRegUsed() but that's only available to CodeGen as far as I can tell. | |
lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h | ||
57 | I think you violate the meaning of 'mutable' here. It's meant to mean that the variable is not part of the externally visible state, but the accessors below make it externally visible. | |
142 | I know what you mean but I haven't seen the 'TU' abbreviation elsewhere. Consider writing 'Translation Unit' instead. | |
154 | llvm_unreachable() is preferable in this case. |
"This will make it difficult to hook MCCodeEmitter::EncodeInstruction(), but overriding MCObjectStreamer::EmitInstToFragment() looks like a suitable alternative"
It's not possible to override that function because it's private. It's possible to override EmitInstruction but we need a custom MCELFStreamer which I added in D3129. That is the start of the implementation of your proposed changes.
I basically agree with MipsReginfo ownership of this functionality, but am too far away from work at this point to do the review well.
Just a quick philosophical point. I like that you guys are encapsulating more of the functionality into the Mips realm. It allows one to operate more naturally for our architecture instead of contorting to generic image seen from the eyes of x86 or ARM. Continue to question private class definitions which should be derivable in order to make Mips code generation more natural.
I will miss you guys. Jack
I think you violate the meaning of 'mutable' here. It's meant to mean that the variable is not part of the externally visible state, but the accessors below make it externally visible.