This is an archive of the discontinued LLVM Phabricator instance.

[mips] Fix generation of .reginfo and .Mips.options.
AbandonedPublic

Authored by matheusalmeida on Mar 11 2014, 7:31 AM.

Details

Reviewers
dsanders
Summary

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.

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.

jacksprat resigned from this revision.Mar 20 2014, 10:21 AM

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

matheusalmeida abandoned this revision.Mar 31 2014, 5:15 AM

Superseded by D3133.