File: occurences.cpp

package info (click to toggle)
faust 0.9.46-2
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd, wheezy
  • size: 15,256 kB
  • ctags: 9,961
  • sloc: cpp: 47,746; sh: 2,254; ansic: 1,503; makefile: 1,211; ruby: 950; yacc: 468; objc: 459; lex: 200; xml: 177
file content (173 lines) | stat: -rw-r--r-- 4,327 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#include <assert.h>
#include <stdlib.h>
#include "recursivness.hh"
#include "occurences.hh"
#include "sigtype.hh"
#include "sigtyperules.hh"
#include <iostream>

using namespace std;

/**
 * Extended Variability with recursiveness indication
 */
static int xVariability (int v, int r)
{
	//cerr << "xVariability (" << v << ", " <<  r << ")" << endl;
	//assert (v < 3);				// kKonst=0, kBlock=1, kSamp=2
	//assert(r==0 | v==2);
	if (r>1) r=1;
	return min(3, v + r);
}

//-------------------------------------------------
//	Occurences methods
//-------------------------------------------------

Occurences::Occurences(int v, int r) : fXVariability(xVariability(v,r)) {
	for (int i=0; i<4; i++) fOccurences[i]=0;
	fMultiOcc = false;
	fMaxDelay = 0;
	fOutDelayOcc = false;
}

Occurences* Occurences::incOccurences(int v, int r, int d) {
	int ctxt = xVariability(v,r);
	//assert (ctxt >= fXVariability);
	fOccurences[ctxt] += 1;
	fMultiOcc = fMultiOcc | (ctxt > fXVariability) | (fOccurences[ctxt] > 1);
	if (d == 0) {
		//cerr << "Occurence outside a delay " << endl;
		fOutDelayOcc = true;
	}
	if (d > fMaxDelay) {
		//cerr << "Max delay : " << fMaxDelay << " <- " << d << endl;
		fMaxDelay = d;
	}
	return this;
}

bool Occurences::hasMultiOccurences()	const	{ return fMultiOcc; }

bool Occurences::hasOutDelayOccurences() const	{ return fOutDelayOcc; }

int Occurences::getMaxDelay() const
{
	return fMaxDelay;
}

//--------------------------------------------------
//	Mark and retrieve occurences of subtrees of root
//--------------------------------------------------

void OccMarkup::mark(Tree root)
{
	fRootTree = root;
	fPropKey = tree(unique("OCCURENCES"));

	if (isList(root)) {
		while (isList(root)) {
			//incOcc(kSamp, 1, hd(root));
			incOcc(nil, kSamp, 0, 0, hd(root));
			root = tl(root);
		}
		//cerr << "END OF LIST IS " << *root << endl;
	} else {
		//incOcc(kSamp, 1, root);
		incOcc(nil, kSamp, 0, 0, root);
	}
}

Occurences* OccMarkup::retrieve(Tree t)
{
	Occurences* p = getOcc(t);
	if (p == 0) {
		//cerr << "No Occurences info attached to : " << *t << endl;
		//exit(1);
	}
	return p;
}

//------------------------------------------------------------------------------
// Increment the occurences of t within context v,r,d and proceed recursively
//------------------------------------------------------------------------------

void OccMarkup::incOcc(Tree env, int v, int r, int d, Tree t)
{
	// Check if we have already visited this tree
	Occurences* occ = getOcc(t);

	if (occ==0) {
		// 1) We build initial occurence information
		Type	ty = getCertifiedSigType(t);
		int v0 = ty->variability();
		int r0 = getRecursivness(t);

		occ = new Occurences(v0,r0);
		setOcc(t, occ);

		// We mark the subtrees of t
        Tree c, x, y, z;
		if (isSigFixDelay(t,x,y)) {
			Type g2 = getCertifiedSigType(y);
			int d2 = checkDelayInterval(g2);
			assert(d2>=0);
			incOcc(env, v0, r0, d2, x);
			incOcc(env, v0, r0, 0, y);
        } else if (isSigPrefix(t,y,x)) {
            incOcc(env, v0, r0, 1, x);
            incOcc(env, v0, r0, 0, y);
        } else if (isSigSelect3(t,c,y,x,z)) {
            // make a special case for select3 implemented with real if
            // because the c expression will be used twice in the C++
            // translation
			incOcc(env, v0, r0, 0, c);
			incOcc(env, v0, r0, 0, c);
            incOcc(env, v0, r0, 0, x);
            incOcc(env, v0, r0, 0, y);
            incOcc(env, v0, r0, 0, z);
        } else {
			vector<Tree> br;
			int n = getSubSignals(t, br);
			if (n>0 && ! isSigGen(t)) {
				for (int i=0; i<n; i++) incOcc(env, v0, r0, 0, br[i]);
			}
		}
	}

	occ->incOccurences(v,r,d);

}



Occurences* OccMarkup::getOcc(Tree t)
{
	Tree p = t->getProperty(fPropKey);
	if (p) {
		return (Occurences*) tree2ptr(p);
	} else {
		return 0;
	}
}


void OccMarkup::setOcc(Tree t, Occurences* occ)
{
	t->setProperty(fPropKey, tree(occ));
}



/**
 * return the position of a signal in the current recursive environment
 * @param env the current recursive environment of the signal
 * @param t signal we want to know the position
 * @return the position in the recursive environment
 */
static int position (Tree env, Tree t, int p)
{
	if (isNil(env)) return 0;	// was not in the environment
	if (hd(env) == t) return p;
	else return position (tl(env), t, p+1);
}