Program Listing for File OperatorAnnotation.h#
↰ Return to documentation for file (src/midend/astUtil/annotation/OperatorAnnotation.h)
#ifndef OPERATOR_ANNOTATION_H
#define OPERATOR_ANNOTATION_H
#include "AnnotCollect.h"
#include "AnalysisInterface.h"
#include "AstInterface.h"
#include <iostream>
#include <list>
template <class Descriptor>
class OperatorAnnotCollection
: public AnnotCollectionBase<OperatorDeclaration>,
public TypeCollection<Descriptor>
{
protected:
using TypeCollection<Descriptor>::typemap;
public:
void read_descriptor( const OperatorDeclaration& target,
const std::string& annot, std::istream& in)
{
Descriptor d;
d.read(in, target);
add_annot( target, d);
}
void add_annot( const OperatorDeclaration& op, const Descriptor& d)
{
std::string sig = op.get_signiture();
this->typemap[ sig ] = d;
}
bool known_operator( AstInterface& fa,
const AstNodePtr& exp, AstInterface::AstNodeList* argp= 0,
Descriptor* desc= 0, bool replpar = false,
Map2Object<AstInterface*, AstNodePtr, AstNodePtr>* astcodegen =0) const
{
AstInterface::AstNodeList args;
AstInterface::AstTypeList params;
AstNodePtr f;
std::string fname;
if (!(fa.IsFunctionCall(exp,&f, &args, 0, ¶ms) && fa.IsVarRef(f,0,&fname))
&& !fa.IsFunctionDefinition(exp,&fname,&args,0,0, ¶ms))
return false;
std::string sig = OperatorDeclaration::get_signiture(fa, fname, params);
if (this->known_type( sig, desc)) {
if (argp != 0)
*argp = args;
if (desc != 0 && replpar) {
ParamDescriptor params = desc->get_param_decl().get_params();
ReplaceParams repl( params, args, astcodegen);
repl.add( "result", exp, astcodegen);
desc->replace_val( repl);
}
return true;
}
return false;
}
};
class OperatorInlineAnnotation
: public OperatorAnnotCollection<OperatorInlineDescriptor>
{
virtual bool read_annot_name( const std::string& annotName) const
{ return annotName == "inline"; }
static OperatorInlineAnnotation* inst;
OperatorInlineAnnotation() {}
public:
static OperatorInlineAnnotation* get_inst()
{ if (inst == 0) inst = new OperatorInlineAnnotation();
return inst; }
void Dump() const
{
std::cerr << "inline: \n";
OperatorAnnotCollection<OperatorInlineDescriptor>::Dump();
}
bool known_operator( AstInterface& fa, const AstNodePtr& exp, SymbolicVal* val = 0) const;
void register_annot()
{ ReadAnnotation::get_inst()->add_OperatorCollection(this); }
//Check if an operator has a 'inline {this.operator_2(dim)' record.
//If yes, store the semantically equivalent operator into val
bool get_inline( AstInterface& fa, const AstNodePtr& h, SymbolicVal* val = 0);
};
class OperatorModInfoCollection
: public OperatorAnnotCollection<OperatorSideEffectDescriptor>
{
virtual bool read_annot_name( const std::string& annotname) const
{ return annotname == "modify"; }
public:
void Dump() const
{
std::cerr << "modify: \n";
OperatorAnnotCollection<OperatorSideEffectDescriptor>::Dump();
}
};
class OperatorReadInfoCollection
: public OperatorAnnotCollection<OperatorSideEffectDescriptor>
{
virtual bool read_annot_name( const std::string& annotname) const
{ return annotname == "read"; }
public:
void Dump() const
{
std::cerr << "read: \n";
OperatorAnnotCollection<OperatorSideEffectDescriptor>::Dump();
}
};
class OperatorSideEffectAnnotation : public FunctionSideEffectInterface
{
OperatorModInfoCollection modInfo;
OperatorReadInfoCollection readInfo;
static OperatorSideEffectAnnotation* inst;
OperatorSideEffectAnnotation() {}
public:
static OperatorSideEffectAnnotation* get_inst()
{ if (inst == 0) inst = new OperatorSideEffectAnnotation();
return inst; }
void register_annot()
{
ReadAnnotation* op = ReadAnnotation::get_inst();
op->add_OperatorCollection(&modInfo);
op->add_OperatorCollection(&readInfo);
}
bool get_modify( AstInterface& fa, const AstNodePtr& fc, CollectObject<AstNodePtr>* collect = 0);
bool get_read( AstInterface& fa, const AstNodePtr& fc, CollectObject<AstNodePtr>* collect = 0);
void Dump() const
{ modInfo.Dump(); readInfo.Dump(); }
};
class OperatorAliasCollection
: public OperatorAnnotCollection <OperatorAliasDescriptor>
{
virtual bool read_annot_name( const std::string& annotname) const
{ return annotname == "alias"; }
public:
void Dump() const
{ std::cerr << "alias: \n";
OperatorAnnotCollection<OperatorAliasDescriptor>::Dump(); }
};
class OperatorAllowAliasCollection
: public OperatorAnnotCollection <OperatorAliasDescriptor>
{
virtual bool read_annot_name( const std::string& annotname) const
{ return annotname == "allow_alias"; }
public:
void Dump() const
{ std::cerr << "allow_alias: \n";
OperatorAnnotCollection<OperatorAliasDescriptor>::Dump(); }
};
class OperatorAliasAnnotation : public FunctionAliasInterface
{
OperatorAliasCollection aliasInfo;
OperatorAllowAliasCollection allowaliasInfo;
virtual bool read_annot_name( const std::string& annotname) const
{ return annotname == "alias" || annotname == "allow_alias"; }
static OperatorAliasAnnotation* inst;
OperatorAliasAnnotation() {}
public:
static OperatorAliasAnnotation* get_inst()
{ if (inst == 0) inst = new OperatorAliasAnnotation();
return inst; }
bool may_alias(AstInterface& fa, const AstNodePtr& fc, const AstNodePtr& result,
CollectObject<std::pair<AstNodePtr,int> >& collectalias);
bool allow_alias( AstInterface& fa, const AstNodePtr& fd,
CollectObject<std::pair<AstNodePtr,int> >& collectalias);
void Dump() const
{ aliasInfo.Dump(); allowaliasInfo.Dump(); }
void register_annot()
{ ReadAnnotation* op = ReadAnnotation::get_inst();
op->add_OperatorCollection(&aliasInfo);
op->add_OperatorCollection(&allowaliasInfo); }
};
//e.g: operator floatArray::operator() (int index) { inline { this.elem(index) }; }
// All ..array(index).. will be replaced by array.elem(index) in the code
class OperatorInlineRewrite : public TransformAstTree
{
public:
virtual bool operator()( AstInterface& fa, const AstNodePtr& n,
AstNodePtr& result)
{
SymbolicVal r;
if (OperatorInlineAnnotation::get_inst()->get_inline( fa, n, &r)) {
result = r.CodeGen(fa);
return true;
}
return false;
}
AstNodePtr operator() ( AstInterface& fa, const AstNodePtr& r)
{
return TransformAstTraverse( fa, r, *this);
}
};
#endif