Otawa  0.10
Properties System

The properties are the first-class citizens of the OTAWA core used to annotate a program representation. More...

Classes

class  otawa::DuplicateIdentifierException
 This exception is thrown when two identifier with the same name are declared. More...
 
class  otawa::AbstractIdentifier
 Represents a unique identifier used by the annotation system. More...
 
class  otawa::DeletableProperty< T >
 A deletable property is a genericproperty whose value will be deleted when the property is destroyed. More...
 
class  otawa::Identifier< T >
 This class represents identifier with a typed associated value. More...
 
class  otawa::GenericProperty< T >
 This generic class allows attaching any type of data to a property. More...
 
class  otawa::LockedProperty< T >
 This class is used for building a lock property, that is, for taking pointer values implementing the elm::Locked class. More...
 
class  otawa::Property
 A property associates a data with an identifier. More...
 
class  otawa::PropList
 This a list of properties. More...
 
class  otawa::PropList::Iter
 This iterator is used for reading all properties of a property list. More...
 
class  otawa::PropList::Getter
 This class is used for accessing all properties of property list with a given identifier. More...
 

Functions

template<>
Identifier< cstringotawa::IDENTIFIER_LABEL ("otawa::IDENTIFIER_LABEL","")
 Property of this identifier is put on identifier to give a more human-readable name to the identifier. More...
 
Identifier< cstringotawa::IDENTIFIER_DESC ("otawa::IDENTIFIER_DESC","")
 Property of this identifier is put on identifier to give a more precise description of the identifier. More...
 
const AbstractIdentifier otawa::END ("end")
 This identifier is used for marking the end of property list definition in variable arguments "...". More...
 

Variables

Identifier< cstring > otawa::IDENTIFIER_LABEL
 Property of this identifier is put on identifier to give a more human-readable name to the identifier. More...
 
Identifier< cstring > otawa::IDENTIFIER_DESC
 Property of this identifier is put on identifier to give a more precise description of the identifier. More...
 
const AbstractIdentifier otawa::END
 This identifier is used for marking the end of property list definition in variable arguments "...". More...
 

Detailed Description

The properties are the first-class citizens of the OTAWA core used to annotate a program representation.

They form a simple and usable facility to attach to/retrieve from the program representation some pieces of information.

Principles

Most OTAWA objects provides a facility to store annotations. These annotations are implemented using otawa::Property to implement annotations and PropList to implement objects supporting annotations. As, in OTAWA, the annotation system is the first-class feature to provide adaptability and extensibility, the C++ API provides a lot of facilities to use them.

An annotation is a pair whose first member is an identifier and the second one is value. The C++ template facilities are used to implemented such a flexible feature.

As the annotations are melted together in a same list, the identifier provides a way to retrieve them from a list. They are implemented using the otawa::Identifier class. In order to achieve uniqueness of identifiers, they must be declared as static variables with a string identifying them. During run-time, OTAWA only accepts one identifier matching a name string. This constraint makes easier and faster the management of identifier and, specialy, the comparison that resumes to a pointer comparison.

Using the properties

A property is composed of:

The properties work as dynamic fields of the object they are hooked to. As C++ does not support such a kind of field, OTAWA encapsulates the management of properties in a specific syntax based on the C++ operator overload ability. So, the syntax to read a property the identifier of which is ''ID'', attached to the object ''list'' (an object that has some properties attached to it is called a property list) is:

ID ( list )

To set a property, one has just to use the same syntax followed by the ''='' equal assignment symbol and the assigned expression. If the annotation is already hooked to the property list, its value is easily replaced.

ID ( list ) = expression ;

The property system allow hooking several properties with the same identifier to a list. The trick is easily performed using the ''add()'' method.

ID ( list ).add( expression );

To retrieve properties with the same identifier, one has to use a clumsy syntax as below:

for(Identifier< data type > data( list , ID ); data; data++) use(data);

The properties may also be removed using the ''remove'' method of the ''Identifier'' class.

ID ( list ) . remove ( ) ;

Although the access time to OTAWA properties is longer than an access to classical C++ fields, the penalty is reduced thanks to a cache system that benefits from the temporal locality of accesses. The properties also have a slightly larger size in memory. Yet, these drawbacks are balanced by the induced improvement in flexibility and usability to work on the program representation.

This section has listed the main primitives used to handle properties. The following section will show how to declare ''Identifier'' objects.

An identifier may be declared as a global variable or a static class member. In the header file, they may be ddeclared as below:

#include <otawa/otawa.h>
extern const Identifier MY_ID;
class C {
static const Identifier YOUR_ID;
};

While, in the source file, they then must be defined:

#include "my_header.h"
const Identifier MY_ID("my_id");
const Identifier C::YOUR_ID("your_id");

Then, they may be used easily by giving their name in the Property and PropList methods:

int value = props.get<int>(MY_ID);

Simple Use of Annotations

As any other property attached to an object, the annotation may be read or written. They works quitely like members of classes bu their dynamic and generic behaviour requires accessing specific methods in the property list.

For setting a property in a property list, one may use the set() method that takes the type of the value to set (often optional), the identifier to use and the value to set. If the property list contains already a property with this identifier, it is removed.

props.set<bool>(C::YOUR_ID, true);
props.set(MY_ID, 1.5);

OTAWA allows also to have many properties with the same identifier in a property list. The add() method must be used in this case:

props.add(C::YOUR_ID, true);
props.add<double>(MY_ID, 1.5);

There are may different methods to read a property from a property list taking in account the presence of the property in the list. The first form of get() method takes the type of the result and the identifier of the looked property. It returns an elm::Option value that may contain or not the property value.

elm::Option<double> result = props.get<double>(MY_ID);
if(result)
// Property found
else
// Property not found

In the second form, the get() takes also a value that is the default returned value if the property is not found.

bool result = props.get<bool>(C::YOUR_ID, false);

Finally, the use() method may speed up the access when the property is known to be in the list. Notice that an "assertion failure" is thrown if the property is not found!

bool result = props.use<bool>(C::YOUR_ID);

Iterator Access

As most object collection in OTAWA, the properties may be visited using iterators with the class Property::PropIter.

for(PropList::PropIter prop(props); prop; prop++) {
cout << "identifier = " << prop->id() << endl;
cout << "value = " << prop.get<int>() << endl;
}

As the use of the PropList::add() method may create many properties with the same identifier, a specific iterator is provided to visit the instances of a same identifier: PropList::PropGetter.

for(PropList::PropGetter prop(props, MY_ID); prop; prop++)
cout << "value = " << prop.get<double>() << endl;

Generic Annotation

Yet, as re-typing at each use the type of annotation value may be painful and also error-prone (there is no type checking between the property creation and the retrieval), OTAWA introduced otawa::GenericIdentifier identifier that embed the type of the associated value. Such an identifier is declared is below:

Header File
GenericIdentifier<int> AN_ID;
Source File
GenericIdentifier<int> AN_ID("an_id");

The, they provides a functional-like notation to read and write the value:

int value = AN_ID(props);
int value = AN_ID(props, 111);
AN_ID(props) = 111;

It is currently the preferred form to use properties but a lot of already- existing identifiers in OTAWA does not already supports this work.

Function Documentation

const AbstractIdentifier otawa::END ( "end"  )

This identifier is used for marking the end of property list definition in variable arguments "...".

Identifier<cstring> otawa::IDENTIFIER_DESC ( "otawa::IDENTIFIER_DESC"  ,
""   
)

Property of this identifier is put on identifier to give a more precise description of the identifier.

Hooks
template<>
Identifier<cstring> otawa::IDENTIFIER_LABEL ( "otawa::IDENTIFIER_LABEL"  ,
""   
)

Property of this identifier is put on identifier to give a more human-readable name to the identifier.

Hooks

Variable Documentation

const AbstractIdentifier otawa::END("end")

This identifier is used for marking the end of property list definition in variable arguments "...".

Identifier<cstring> otawa::IDENTIFIER_DESC("otawa::IDENTIFIER_DESC","")

Property of this identifier is put on identifier to give a more precise description of the identifier.

Hooks

Referenced by otawa::idDesc().

Identifier<cstring> otawa::IDENTIFIER_LABEL("otawa::IDENTIFIER_LABEL","")

Property of this identifier is put on identifier to give a more human-readable name to the identifier.

Hooks

Referenced by otawa::idLabel().