Support for bundles of MCInst?

Hello all,

We're developing an integrated assembler for a VLIW target, and some of the
optimizing our assembler needs to do must be done on a per-packet basis.
This requires us to be able to traverse instruction within a packet, and one
particular optimization requires traversal of previous packets as well.

We're considering adding support for MCInst bundles in the MC layer to
accommodate this use case, analogous to what currently exists for
MachineInstr. Has anyone given thought to this before? Is there already a
way to create bundles in the MC layer that we've overlooked?

Any comments or suggestions are appreciated.

Thanks,

Could you elaborate on this proposal in a bit more detail? What will
the semantics of these MCInst bundles be, how will they be generated,
and what special treatment will they get from the assembler?

Thanks in advance,
Eli

Mario,

Hello Eli,

Could you elaborate on this proposal in a bit more detail? What will the

semantics

of these MCInst bundles be, how will they be generated, and what special
treatment will they get from the assembler?

Thanks for your reply. There is no proposal as of yet, I first wanted to
check and see if a) there was already a way to do this in the MC layer, and
b) if not, if anyone had already come up with ideas on how to approach it.

- --
Mario Guerra
mariog@codeaurora.org
Qualcomm Innovation Center Inc is a member of Code Aurora Forum, hosted by
The Linux Foundation

Hello Owen,

There should already be sufficient support for what you're trying to do.

See

MCOperand::CreateInst(). The concept is that you'll build a composite

MCInst in

your AsmPrinter::EmitInstruction() method, which uses Inst-type MCOperands

to

hold a list of sub-instructions. Then you call

AsmStreamer::EmitInstruction() on the

composite MCInst.

Thanks for your reply. This is actually one approach we are considering, but
there are a few issues with it we weren't sure how to address.

One is that the lifespan of an MCInst seems to be limited to the scope of
AsmPrinter, and we need them to be persistent in order to do a traversal for
branch relaxation and fetch boundary alignment optimizations. Furthermore,
even if they were persistent there doesn't seem to be a way to traverse
MCInst objects due to a lack of iterator support. Have we overlooked this
functionality? If not, does it make sense for us to add it?

Those issues aside, it sounds like the streamer already understands how to
process and print sub-instructions, which is good. Will the size of the
packet be properly accounted for by the MCObjectStreamer if we have to pad
the packet (mainly for fetch alignment)?

Thanks,
- --
Mario Guerra
mariog@codeaurora.org
Qualcomm Innovation Center Inc is a member of Code Aurora Forum, hosted by
The Linux Foundation

Mario,

Thanks for your reply. This is actually one approach we are considering, but
there are a few issues with it we weren't sure how to address.

One is that the lifespan of an MCInst seems to be limited to the scope of
AsmPrinter, and we need them to be persistent in order to do a traversal for
branch relaxation and fetch boundary alignment optimizations.

This is no different than any other MCInst in the course of object emission. Normal MCInst's are allocated on the stack in the AsmPrinter.

Furthermore,
even if they were persistent there doesn't seem to be a way to traverse
MCInst objects due to a lack of iterator support. Have we overlooked this
functionality? If not, does it make sense for us to add it?

There's no C++ style iterators, but there are perfectly-function C style getNumOperands() and getOperand() methods. It might be nice to add the former, but you should be able to do everything you need with the latter.

Those issues aside, it sounds like the streamer already understands how to
process and print sub-instructions, which is good.

Actually, no. The streamer knows nothing at all about sub-instructions. It's the responsibility of the printInstruction/encodeInstruction methods in your printer or decoder know that they need to recurse onto the contents of the bundle.

Will the size of the
packet be properly accounted for by the MCObjectStreamer if we have to pad
the packet (mainly for fetch alignment)?

The MC system (including relaxation) is capable of handling instructions with variable length encodings whose size can't be determined until the MCCodeEmitter step.

--Owen

Owen,

Owen,

> One is that the lifespan of an MCInst seems to be limited to the scope
> of AsmPrinter, and we need them to be persistent in order to do a
> traversal for branch relaxation and fetch boundary alignment

optimizations.

This is no different than any other MCInst in the course of object

emission. Normal

MCInst's are allocated on the stack in the AsmPrinter.

That's the crux of our problem. The short lifespan of an MCInst prevents us
from being able to perform some of the optimizations we need at the MC level
that require the ability to traverse previous packets. We could do these
optimizations at the MI level before lowering, but then they would be missed
by the assembly parser since it goes directly to MC.

Speaking of the assembly parser, we also need to be able build packets in
the parser. It currently operates on a single instruction at a time, so
building composite instructions in the parser would require some changes. I
don't know what those changes would look like yet, but it's worth mentioning
in this context.

- --
Mario Guerra
mariog@codeaurora.org
Qualcomm Innovation Center Inc is a member of Code Aurora Forum, hosted by
The Linux Foundation

In terms of understanding the infrastructure, I don't know a better way than reading the code.
For implementing instructions with variable sizes is easy: the MCCodeEmitter just receivers a streamer to send encoded bytes to, and an MCInst to encode. You can feed as many bytes to the streamer as you want.
For implementing relaxation, you're probably best off looking at an existing implementing. X86AsmBackend might be a reasonable place to start.

--Owen