Proposal for Adding MetaData to a BasicBlock

Hello group,

Per my posting on the Clang Newsgroup.

I’m interested in doing some loop optimizations, towards this end I would like to add some custom Metadata to a Loop header.

Loops in LLVM are represented using BasicBlocks, but unfortunately you can NOT add MetaData to a BasicBlock. Although you can add Metadata to an instruction. So I’m proposing to add the Metadata manipulation methods and state from class “Instruction” to class “BasicBlock”.

The class “Instruction” stores a private enumeration:

enum
{
// HasMetadataBit - This is a bit stored in the SubClassData field which
// indicates whether this instruction has metadata attached to it or not.

HasMetadataBit = 1 << 15
};

This enumeration is then utilized by hasMetadata() which is inlined in class Instruction:

// hasMetadata() - Return true if this instruction has any metadata attached to it.

bool hasMetadata() const
{
return (getSubclassDataFromValue() & HasMetadataBit) != 0;
}

First Question:

Since I do not expect to require any subclasses of BasicBlock, should I just implement in BasicBlock the following:

bool hasMetadata() const
{
return (HasMetadataBit) != 0;
}

Second Question:

Additionally, after studying the way Metadata is manipulated in class “Instruction”, I propose to add the following methods from class “Instruction” to class “BasicBlock”:

public:
bool hasMetadata() const
MDNode *getMetadata(unsigned KindID) const;
MDNode *getMetadata(const char Kind) const;
void getAllMetadata(SmallVectorImpl<std::pair<unsigned, MDNode
> > &MDs)const;
void setMetadata(unsigned KindID, MDNode *Node);
void setMetadata(const char *Kind, MDNode *Node);

private:
// These are all implemented in Metadata.cpp.
MDNode *getMetadataImpl(unsigned KindID) const;
MDNode *getMetadataImpl(const char Kind) const;
void getAllMetadataImpl(SmallVectorImpl<std::pair<unsigned,MDNode
> > &)const;
void removeAllMetadata();

I noticed that BasicBlock seems to be referenced by almost every class in LLVM, so I wanted to ask which particular client classes I will need to update so I don’t break any existing code. It seems to me, that all I’m doing is adding code, so I shouldn’t break any of the client classes, but I will need to update the classes that will need to utilize these new methods in class BasicBlock.

Per Chris’s earlier comment, I realize that BitcodeReader / BitcodeWriter & LLParser will need to be updated. For the moment I am just trying to make sure that I can procedurally add Metadata to a Loop Header via adding Metadata to a BasicBlock.

Third Question:

I had some trouble understanding the implementation of SetMetadata in the Instruction class, is this where Metadata is “attached” to an Instruction?

Any detailed comments / suggestions as to which client LLVM IR classes I need to dig into as well as what all the changes I will have to make would be greatly appreciated.

Thanks,

kalyan ponnala wrote:

Hello group,

Per my posting on the Clang Newsgroup.

I'm interested in doing some loop optimizations, towards this end I would like to add some custom Metadata to a Loop header.

Loops in LLVM are represented using BasicBlocks, but unfortunately you can NOT add MetaData to a BasicBlock. Although you can add Metadata to an instruction. So I'm proposing to add the Metadata manipulation methods and state from class "Instruction" to class "BasicBlock".

I have also needed to add meta-data to basic blocks for a research project on which I'm working. I have written an implementation in LLVM 2.6 and will probably port the implementation to LLVM 2.7, so I've done some thinking about how to do it in both versions.

Here are some thoughts for you to think about:

1) In LLVM 2.6 (and probably LLVM 2.7), you can, in fact, add metadata that contains a Basic Block because BasicBlock derives from Value (I create MDNodes that contain a BasicBlock * as one of its elements). However, you can't write the bitcode out to disk (because the BitcodeWriter pass can't handle it). What I did in my code was to write one pass that adds the meta-data and another that removes it. In this way, other passes can use the metadata, but it gets removed right at the end of my transforms.

2) For LLVM 2.7., I was thinking that I could add meta-data to the BasicBlock's terminator instruction. Each BasicBlock has a unique Terminator instruction; adding metadata to it is similar to adding metadata to the BasicBlock itself.

3) Make sure that adding meta-data is what you really need to do. If you're writing an analysis which can be safely recomputed on demand, then it would be better to implement an LLVM analysis pass that computes the data you need and have your transform pass(es) query it for the information they need. The Pass Manager will (re)run your analysis pass when it is required.

-- John T.

I had some trouble understanding the implementation of SetMetadata in the
Instruction class, is this where Metadata is "attached" to an Instruction?

Yes.

Any detailed comments / suggestions as to which client LLVM IR classes I
need to dig into as well as what all the changes I will have to make would
be greatly appreciated.

As John said, if you attaching metadata to basic block terminator
works for you then it is the best approach. Otherwise

1) You need to propose LLVM IR syntax change to attach metadata with a
BasicBlock. The implementation for this would require changes in
AsmParser and AsmWriter.
2) As you know, you need bitcode reader/writer changes
3) You need doc changes
4) You will have to touch LLVMContext related code
5) You may need to update BasicBlock manipulation APIs (e.g. clone,
split, merge) to preserve/destroy/update metadata.