This is an archive of the discontinued LLVM Phabricator instance.

[mips] Add MipsOptionRecord abstraction.
ClosedPublic

Authored by tomatabacu on Mar 20 2014, 8:00 AM.

Details

Summary

This abstraction was created to help storing arbitrary information in ELF files.
For example, register usage can be stored in Mips specific ELF sections like .Mips.options.
Arbitrary records of .Mips.options should subclass MipsOptionRecord and provide
an implementation to EmitMipsOptionRecord.

The MipsELFStreamer class owns all the records and is responsible for their
creation and destruction.

Diff Detail

Event Timeline

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

Keeping in mind that I am drifting away from code and into retirement:

I am concerned that we have to loop through every potential register for each instruction register operand to determine use. Is there not a quicker way to do this? How does the codegen do it? Can it be done with a mask?

Does this routine get called for both direct object and asm?

Is this shared with .reginfo generation? I think so, but it wasn't obvious.

Jack

I am concerned that we have to loop through every potential register for each instruction register operand to determine use. Is there not a quicker way to do this? How does the codegen do it? Can it be done with a mask?

Not as far as I know. CodeGen uses the MachineRegisterInfo as the main abstraction to keep track of registers and afaik this is not accessible from the MC layer.

Does this routine get called for both direct object and asm?

Yes. For assembly input it's called from MipsAsmParser::MatchAndEmitInstruction and from direct object emission it's called from MipsAsmPrinter::EmitInstruction which calls EmitToStreamer which then calls the EmitInstruction in the ELF streamer.

Is this shared with .reginfo generation? I think so, but it wasn't obvious.

Yes. I wrote this comment that explains the logic of handling .Mips.options and .reginfo in the same function.

// We need to distinguish between N64 and the rest because at the moment
// we don't emit .Mips.options for other ELFs other than N64.
// Since .reginfo has the same information as .Mips.options (ODK_REGINFO),
// we can use the same abstraction (MipsRegInfo class) to handle both.

If it's not clear, please say so.

matheusalmeida updated this revision to Unknown Object (????).Mar 21 2014, 4:45 AM

MipsELFStreamer now access MCInstrDesc from a global array defined in MipsGenInstrInfo.inc.
This is much better than accessing it via MipsMCCodeEmitter.

All nits except for the MipsELFStreamer destructor

lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h
30–31

They can't be null so I'd make them references instead of pointers.

38–50

This should delete any MipsOptionRecord in MipsOptionRecords.

40

Add a doc comment describing the extra bit it does.

42–43

Drop the 'As the name suggests' and use '///' so it shows up in doxygen.

lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp
30

Is the T.isArch64Bit() necessary? I think testing for N64 is enough.

matheusalmeida updated this revision to Unknown Object (????).Mar 24 2014, 3:44 AM

Addressing concerns.

The destructor in MipsELFStreamer now deletes all the stored MipsOptionRecord* in the vector. The vector is still a vector of pointers because it's not possible to have a vector of references.
Added doxygen style comments to the suggested functions.
Removed superfluous T.isArch64Bit() check.

dsanders accepted this revision.Mar 25 2014, 9:02 AM

LGTM. Just one nit about the comments

lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h
45

I've had previous feedback asking me not to repeat the function name in the comment.

tomatabacu commandeered this revision.Jul 8 2014, 3:25 AM
tomatabacu added a reviewer: matheusalmeida.
tomatabacu added a subscriber: tomatabacu.

Commandeered to finish off the patch and make it ready for commit.

tomatabacu updated this revision to Diff 11153.Jul 8 2014, 5:15 AM
tomatabacu edited edge metadata.

Rebased to trunk.

For MipsELFStreamer.h:
Reordered #include directives to conform with the recommended lexicographical order.
Renamed the EmitOptionRecords() to EmitMipsOptionRecords().

For MipsELFStreamer.cpp:
Removed anonymous namespace and made the getInstDesc function static instead.
Replaced call to Context.getRegisterInfo() with the appropriate local variable, MCRegInfo, when assigning to RegClassID.
Refactored for loop inside EmitMipsOptionRecords() to a range-based for loop.

For MipsTargetStreamer.cpp:
Replaced call to EmitOptionRecords() with EmitMipsOptionRecords().

tomatabacu updated this revision to Diff 11155.Jul 8 2014, 5:22 AM
tomatabacu edited edge metadata.

Fixed formatting for the SmallVector<MipsOptionRecord *, 8> type.

matheusalmeida edited edge metadata.Jul 8 2014, 1:31 PM

Hi Toma,

(Obviously) Feel free to commit. The reason I haven't done so (and I apologise!) was because I had some troubles convincing the dmz portal buildbots to pick up changes from my branch so that I could run the llvm test suite and then I forgot about this patch...

Regards,
Matheus

Toma doesn't have commit access yet so I'll be committing for him for the first few patches.

The status of C++11 has moved on since I last reviewed this patch. It was quite new at the time but is now fairly well tested so I'd like to use unique_ptr to remove the need for explicit memory management of the new objects. This will also fix a memory leak I failed to spot. I'd also like to try the MCSubRegIterator technique mentioned in one of the FIXME comments to try and avoid the reference to MipsInsts if possible.

lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h
30–31

We should make both of these use unique_ptrs. This removes the need for a destructor and fixes the memory leak caused by forgetting to delete RegInfo.

49

Blank line needed above comment. As mentioned earlier in the review, I've been asked not to repeat the function name in the comment.

lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp
67–68

We should definitely try to do this before we commit this patch. It should be a fairly easy change and removes the need to test register class membership which in turn removes the need to reference the internals of the tablegen-erated code.

tomatabacu updated this revision to Diff 11371.Jul 14 2014, 5:40 AM
tomatabacu edited edge metadata.

MipsELFStreamer.h:
Converted existing raw pointers to the shared_ptr type.
Removed destructor.
Fixed blank line and function names in comments.
Removed unused header:

#include "llvm/Support/raw_ostream.h"

Added header for smart pointers:

#include <memory>

MipsELFStreamer.cpp:
Renamed NumOp to OpIndex, for clarity.
Moved the RegClass related code from EmitInstruction to the MipsRegInfoRecord class.
Removed declaration of MipsInsts[].
Removed definition of getInstDesc.
Removed the following unused headers:

#include "MipsMCTargetDesc.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/ELF.h"

MipsOptionRecord.h:
Renamed MipsRegInfo to MipsRegInfoRecord.
Changed the arguments for SetPhysRegUsed().
Added private members of MCRegisterClass type which are used when checking if a given
register belongs to a class in SetPhysRegUsed.
Replaced ri_gp_value64 and ri_gp_value32 with a single 64-bit ri_gp_value.
Removed the following unused headers:

#include "llvm/MC/MCELFStreamer.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Support/DataTypes.h"

Added the following headers:

#include "MipsMCTargetDesc.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCRegisterInfo.h"

Removed the following unnecessary forward declarations:

class MCContext;
class MCELFStreamer;
class MCStreamer;

MipsOptionRecord.cpp:
In MipsRegInfoRecord::EmitMipsOptionRecord, changed code to use a single ri_gp_value.
MipsRegInfoRecord::SetPhysRegUsed is now using MCSubRegIterator to set the mask correctly.
MipsRegInfoRecord::SetPhysRegUsed is no longer checking RegClassIDs and instead uses the
MCRegisterClass private members.
Removed the following unused headers:

#include "MipsMCTargetDesc.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCStreamer.h"

This is nearly ready to commit. You just need to reduce the MSA register set membership tests to (any) one of the MSA register classes, undo the two incidental comment changes (the changes aren't wrong, they just belong in another patch), and add the missing newline at EOF.

One other thing to mention is that you're going a bit too far with the detail in your updates at the moment. You need to describe what you changed (e.g. algorithm or general approach) and why but you don't need to describe the mechanical changes used to accomplish it.
For example, I would describe your latest update like this:

Removed the need to access internals of the tablegen-erated code (MipsInsts)
to determine register usage. The new implementation uses MCSubRegIterator instead.

Use shared_ptr for .MIPS.option records. unique_ptr cannot be used since the
pointer is shared between MipsOptionRecords and RegInfoRecord.

Renamed MipsELFStreamer::RegInfo and MipsRegInfo class to avoid confusion with
TargetRegisterInfo and other uses of the term 'RegInfo'.

Merge ri_gp_value32 and ri_gp_value64 into a single variable (ri_gp_value) and check
for overflow when writing the 32-bit case

Unfortunately, it's rather difficult to write guidelines for what needs mentioning and what you can have the patch say for itself. You'll gradually get a feel for the level of detail that's needed.

lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h
44

Try to avoid making incidental changes in the same patch since they can make the patch noisy and difficult to review. This should be a separate cleanup patch if we decide to do it. For comments that repeat the function name like this, we generally leave the existing cases until we need to change the comment or the related function.

50

Another incidental change.

lib/Target/Mips/MCTargetDesc/MipsOptionRecord.cpp
79–82

It's not necessary to test all four of these MSA classes since they all contain the same registers. We only need to test one (it doesn't matter which).

93

Missing newline at EOF

lib/Target/Mips/MipsOptionRecord.h
56–59

As above, we only need one of these.

dsanders added inline comments.Jul 14 2014, 7:19 AM
lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h
44

My apologies. This isn't an incidental change, I was looking at the diff-between-diffs view.

50

This one isn't incidental either. Sorry for the noise.

tomatabacu updated this revision to Diff 11427.Jul 15 2014, 3:08 AM

Addressed concerns and reflowed comments in MipsELFStreamer.h.
Rebased to trunk (also integrated alignment setting for ".MIPS.options" and ".reginfo").
Fixed tests broken by rebase.

tomatabacu updated this revision to Diff 11644.Jul 18 2014, 9:14 AM

Changed shared_ptr members to uniqe_ptr vector and raw pointer variable.

Fixed abiflags.s tests to not have strict checks on the section header string table
offset.

Fix alignment for .reginfo (because of rebase).

Rebased to trunk.

tomatabacu updated this revision to Diff 11708.Jul 21 2014, 6:24 AM

Fixed formatting.

dsanders closed this revision.Jul 21 2014, 6:39 AM

LGTM. Committed in r213522