[llvm-commits] [llvm] r82060 - in /llvm/trunk: include/llvm/LLVMContext.h include/llvm/Metadata.h include/llvm/Value.h lib/VMCore/LLVMContext.cpp lib/VMCore/LLVMContextImpl.h lib/VMCore/Metadata.cpp lib/VMCore/Value.cpp
Chris Lattner
clattner at apple.com
Sun Sep 27 15:27:34 PDT 2009
On Sep 16, 2009, at 11:09 AM, Devang Patel wrote:
> URL: http://llvm.org/viewvc/llvm-project?rev=82060&view=rev
> Log:
> Add llvm::Metadata to manage metadata used in a context.
> This interface will be used to attach metadata with an instruction.
Hi Devang,
Just getting caught up on commits...
> +++ llvm/trunk/include/llvm/Metadata.h Wed Sep 16 13:09:00 2009
+#include "llvm/ADT/SmallSet.h"
This isn't needed, please remove.
> +//
> =
> =
> =
> ----------------------------------------------------------------------=
> ==//
> +/// Metadata -
> +/// Metadata manages metadata used in a context.
> +
> +/// MDKindID - This id identifies metadata kind the metadata store.
> Valid
> +/// ID values are 1 or higher. This ID is set by RegisterMDKind.
> +typedef unsigned MDKindID;
> +class Metadata {
Please rename this MetadataContext or something like that. This class
*isn't* metadata, it is meta-metadata :).
Also, please don't use global typedefs like MDKindID. If it is
important enough to give the type a name (other than 'unsigned'),
please use a wrapper struct so that it is "a type safe typedef".
> +private:
> + typedef std::pair<MDKindID, WeakVH> MDPairTy;
> + typedef SmallVector<MDPairTy, 2> MDMapTy;
> + typedef DenseMap<const Instruction *, MDMapTy> MDStoreTy;
> +
> + /// MetadataStore - Collection of metadata used in this context.
> + MDStoreTy MetadataStore;
> +
> + /// MDHandlerNames - Map to hold metadata handler names.
> + StringMap<unsigned> MDHandlerNames;
It is unfortunate that implementation details of this class require
pulling in #includes. Please change these to be void*'s in the header
and cast to the right type in the .cpp file. An example of this is
llvm/Target/TargetLoweringObjectFile.h with "UniquingMap".
Alternatively, put all of this stuff into a "MetadataContextImpl"
class, and make this class have a pointer to that.
> +public:
> +
> + /// RegisterMDKind - Register a new metadata kind and return its
> ID.
> + /// A metadata kind can be registered only once.
> + MDKindID RegisterMDKind(const char *Name);
> +
> + /// getMDKind - Return metadata kind. If the requested metadata
> kind
> + /// is not registered then return 0.
> + MDKindID getMDKind(const char *Name);
The doxygen comment for this class should explain that this class is
the thing that handles uniquing and assignment of IDs for custom
metadata types, and should explain the restrictions on the names.
> + /// getMD - Get the metadata of given kind attached with an
> Instruction.
> + /// If the metadata is not found then return 0.
> + MDNode *getMD(MDKindID Kind, const Instruction *Inst);
> +
> + /// setMD - Attach the metadata of given kind with an Instruction.
> + void setMD(MDKindID Kind, MDNode *Node, Instruction *Inst);
This should probably be named "AddMD" not "setMD". "set" implies that
there can only be one.
There should also be a "remove" method.
> +
> + /// ValueIsDeleted - This handler is used to update metadata store
> + /// when a value is deleted.
> + void ValueIsDeleted(Value *V) {}
> + void ValueIsDeleted(const Instruction *Inst);
Is there any reason that Value needs to explicitly know about this?
Why not use the existing CallbackVH interfaces? If it would be much
more inefficient or something, then I can see having a custom
extension like this, but it would be nice to minimize this if possible.
> +++ llvm/trunk/lib/VMCore/Metadata.cpp Wed Sep 16 13:09:00 2009
> @@ -15,6 +15,7 @@
> #include "llvm/Metadata.h"
> #include "llvm/LLVMContext.h"
> #include "llvm/Module.h"
> +#include "llvm/Instruction.h"
> #include "SymbolTableListTraitsImpl.h"
> using namespace llvm;
>
> @@ -251,3 +252,74 @@
> NamedMDNode::~NamedMDNode() {
> dropAllReferences();
> }
> +
> +//
> =
> =
> =
> ----------------------------------------------------------------------=
> ==//
> +//Metadata implementation
> +//
> +
> +/// RegisterMDKind - Register a new metadata kind and return its ID.
> +/// A metadata kind can be registered only once.
> +MDKindID Metadata::RegisterMDKind(const char *Name) {
This needs to enforce various constraints on the name. For example,
you can't have a space in the name etc. Whatever requirements the .ll
lexer have should be enforced here with an assert.
> + MDKindID Count = MDHandlerNames.size();
> + StringMap<unsigned>::iterator I = MDHandlerNames.find(Name);
> + assert(I == MDHandlerNames.end() && "Already registered MDKind!");
Please only do the lookup in MDHandlerNames.find when assertions are
enabled.
> + MDHandlerNames[Name] = Count + 1;
> + return Count + 1;
> +}
> +
> +/// getMDKind - Return metadata kind. If the requested metadata kind
> +/// is not registered then return 0.
> +MDKindID Metadata::getMDKind(const char *Name) {
> + StringMap<unsigned>::iterator I = MDHandlerNames.find(Name);
> + if (I == MDHandlerNames.end())
> + return 0;
> +
> + return I->getValue();
> +}
> +
> +/// setMD - Attach the metadata of given kind with an Instruction.
> +void Metadata::setMD(MDKindID MDKind, MDNode *Node, Instruction
> *Inst) {
> + MDStoreTy::iterator I = MetadataStore.find(Inst);
> + Inst->HasMetadata = true;
> + if (I == MetadataStore.end()) {
> + MDMapTy Info;
> + Info.push_back(std::make_pair(MDKind, Node));
> + MetadataStore.insert(std::make_pair(Inst, Info));
> + return;
> + }
> +
> + MDMapTy &Info = I->second;
> + Info.push_back(std::make_pair(MDKind, Node));
> + return;
It is simpler to write this as:
void Metadata::setMD(MDKindID MDKind, MDNode *Node, Instruction *Inst) {
asert(Node == 0 && "Use removeMD to remove metadata");
Inst->HasMetadata = true;
MDMapTy &Entry = MetadataStore[I];
if (Entry doesn't already have a "MDKind" entry)
Entry.push_back(std::make_pair(MDKind, Node));
else // Otherwise replace it.
Entry[j] = Node;
}
We don't want to allow multiple entries for one MDKind.
> +/// getMD - Get the metadata of given kind attached with an
> Instruction.
> +/// If the metadata is not found then return 0.
> +MDNode *Metadata::getMD(MDKindID MDKind, const Instruction *Inst) {
> + MDNode *Node = NULL;
> + MDStoreTy::iterator I = MetadataStore.find(Inst);
> + if (I == MetadataStore.end())
> + return Node;
> +
> + MDMapTy &Info = I->second;
> + for (MDMapTy::iterator I = Info.begin(), E = Info.end(); I != E; +
> +I)
> + if (I->first == MDKind)
> + Node = dyn_cast_or_null<MDNode>(I->second);
We shouldn't allow duplicates, so this can be simplified to early
return when MDKind is found. You can eliminate the Node variable.
> +/// ValueIsDeleted - This handler is used to update metadata store
> +/// when a value is deleted.
> +void Metadata::ValueIsDeleted(const Instruction *Inst) {
> + // Find Metadata handles for this instruction.
> + MDStoreTy::iterator I = MetadataStore.find(Inst);
> + if (I == MetadataStore.end())
> + return;
This is a serious logic error if HasMetadata is set on an instruction
but it doesn't have an entry in MetadataStore.
> + MDMapTy &Info = I->second;
> +
> + // FIXME : Give all metadata handlers a chance to adjust.
> +
> + // Remove the entries for this instruction.
> + Info.clear();
> + MetadataStore.erase(Inst);
This should erase(I) to avoid having to do another lookup.
-Chris
More information about the llvm-commits
mailing list