Otawa  0.10
Parametric Features and Processor

Usual features and associated processors are defined for computing exactly one feature. More...

Classes

class  otawa::ActualFeature
 An actual feature is the result of the instantiation of a parametric feature. More...
 
class  otawa::ParamFeature
 A parametric feature is a feature that may be instantiated according to some parameters passed in a property list. More...
 
class  otawa::AbstractParamIdentifier
 A parametric identifier allows to instantiate identifier depending on a parametric feature. More...
 
class  otawa::ParamIdentifier< T >
 Implementation of AbstractParamIdentifier for an Identifier. More...
 
class  otawa::AbstractParamProcessor
 Abstract form of a parametric processor. More...
 
class  otawa::ParamProcessor
 A parametric processor allows to generate processor for parametric feature. More...
 

Detailed Description

Usual features and associated processors are defined for computing exactly one feature.

Yet, several features in the WCET computation may have the same behaviour but with different configurations. For example, in several microprocessors, we may have several levels of cache (L1, L2, ...) exhibiting the same behaviour but with different configurations.

Declaring and requiring

Parametric and processors allows to use the same feature/processors system for different facilities in a WCET computation. Basically, a parametric feature is a feature generator. The feature are identified by specific parameters passed to the parametric feature. For the example of a cache, the parameter may be the description of the cache. Once the parameter is passed, the actual feature may be generated by the parametric feature. The code belows continue with the example of the cache and show the declaration of the parametric feature in a header file.

extern Identifier<hard::Cache *> CACHE;
extern ParamFeature CACHE_SUPPORT;

A processor that has to require the feature with a given cache has to obtain the actual feature from the paramtric feature and to require it:

UserProcessor::UserProcessor(hard::Cache *cache) {
PropList params;
CACHE(params) = cache;
ActualFeature *cache_feature = CACHE_SUPPORT.get(params);
require(cache_feature);
}

Using the parametric feature

Getting an actual feature is not enough to use it. Indeed, each actual feature has its own set of identifier to use to hook annotation on the program representation. When a parametric feature is instantiated into an actual feature, it also instantiates a set of parametric identifiers. The instantiated identifiers are then hooked to be used by the requirer processor.

The code below show how to declare parametric identifiers:

extern Identifier<hard::Cache *> CACHE;
extern ParamFeature CACHE_SUPPORT;
extern ParamIdentifier<category_t> CATEGORY;

The requirer processor then may use the instantiated identifier to retrieve annotation put on the program representation:

class UserProcessor: public BBprocessor {
public:
UserProcessor::UserProcessor(hard::Cache *cache) {
PropList params;
CACHE(params) = cache;
ActualFeature *cache_feature = CACHE_SUPPORT.get(params);
require(cache_feature);
CAT = &CATEGORY.instantiate(cache_feature);
}
protected:
void processBB(WorkSpace *ws, CFG *cfg, BasicBlock *bb) {
category_t *cat = (*CAT)[bb];
...
}
private:
Identifier<category_t> *CAT;
};

Implementing the parametric processor

A parametric processor is processor implementing a parametric feature. Usually, a default parametric processor is passed as parameter to a default feature and used to generate a processor customized with an actual feature.

From the example below, we get below the source file of the parametric feature and its parametric processor:

class CacheProcessor {
};
ParamProcessor CACHE_PROCESSOR("CACHE_PROCESSOR", Version(1, 0, 0), new ParamProcessor::Maker<CacheProcessor>());
Identifier<hard::Cache *> CACHE("CACHE");
ParamFeature CACHE_SUPPORT("CACHE_SUPPORT", CACHE_PROCESSOR);
ParamIdentifier<category_t> CATEGORY(CACHE_SUPPORT, "CATEGORY");

In this example, the default processor implementation is given by the CacheProcessor class. This cache must have a constructor taking as parameter the name, the version and the actual feature. This actual feature is used by the processor to get instantiation parameters and instantiated parametric identified associated with the feature. The code below continues the example:

class CacheProcessor: public BBProcessor {
public:
CacheProcessor(cstring name, Version version, AcutalFeature *feature)
: BBProcessor(name, version), cache(CACHE(feature)), CAT(CATEGORY(feature))
{ }
protected:
void processBB(WorkSpace *ws, CFG *cfg, BasicBlock *bb) {
CAT(bb) = computeCategory(bb);
}
private:
hard::Cache *cache;
Identifier<category_t>& CAT;
};

In fact, the actual features contains two sets of annotations: