1 /* file "named_lin_ineq.h" */
3 /* Copyright (c) 1994 Stanford University
7 This software is provided under the terms described in
8 the "suif_copyright.h" include file. */
10 #include <suif_copyright.h>
14 #ifndef NAMED_LIN_INEQ_H
15 #define NAMED_LIN_INEQ_H
17 enum name_table_entry_kind
{ nte_none
,
28 /**************************************************************************
30 *** The name of each column. ***
32 **************************************************************************/
33 class name_table_entry
{
34 friend class name_table
;
35 name_table_entry_kind knd
;
43 name_table_entry() { init(); }
44 name_table_entry(const immed
& im
) { init(im
); }
45 name_table_entry(name_table_entry_kind k
,
46 const immed
& nm
) { init(k
, nm
); }
49 void init() { knd
= nte_none
;
53 void init(const immed
&);
54 void init(name_table_entry_kind k
, const immed
& nm
);
55 void init(const name_table_entry
&);
56 void operator=(const name_table_entry
&nte
) { init(nte
); };
59 const char * string() const;
60 var_sym
* var() const { assert(is_var
);
64 void set_name(const immed
&);
66 name_table_entry_kind
kind() const { return knd
; }
75 boolean
operator==(const name_table_entry
& nte
) const;
76 boolean
operator!=(const name_table_entry
& nte
) const
77 { return !(*this == nte
); }
79 base_symtab
* get_symtab(base_symtab
* in
= NULL
) const;
81 void print(FILE * fp
=stdout
) const;
85 /**************************************************************************
87 *** A list of names identifying all the column. ***
89 *** The 0th column is for the constant, thus does not have a name. ***
90 *** All the other columns will be named by entries in the table ***
92 **************************************************************************/
97 void resize(int newsz
);
99 name_table() { L
= NULL
; sz
= 1; rsz
= 1; }
100 name_table(const name_table
* nt
) { L
= NULL
; sz
= 1; rsz
= 1; init(*nt
); }
101 name_table(const name_table
& nt
) { L
= NULL
; sz
= 1; rsz
= 1; init(nt
); }
102 name_table(int s
) { L
= NULL
; sz
= 1; rsz
= 1; init(s
); }
103 name_table(const immed
* v1
, const immed
* v2
=NULL
,
104 const immed
* v3
=NULL
, const immed
* v4
=NULL
,
105 const immed
* v5
=NULL
, const immed
* v6
=NULL
,
106 const immed
* v7
=NULL
, const immed
* v8
=NULL
,
107 const immed
* v9
=NULL
, const immed
* v10
=NULL
,
108 const immed
* v11
=NULL
, const immed
* v12
=NULL
,
109 const immed
* v13
=NULL
, const immed
* v14
=NULL
,
110 const immed
* v15
=NULL
, const immed
* v16
=NULL
);
112 void init(const name_table
&);
115 name_table
&operator=(const name_table
&other
);
117 int n() const { return sz
; }
118 name_table_entry
& operator[](int i
) { assert((i
>=1)&&(i
<sz
));
120 const name_table_entry
& e(int i
) const { assert((i
>=1)&&(i
<sz
));
123 int find(const name_table_entry
&) const;
124 int find(const immed
& vs
) const;
126 void remove(int i
, int j
);
127 void remove(int i
) { remove(i
, i
); }
128 void remove(const integer_row
&rem
);
129 void insert(const name_table_entry
& nte
, int i
);
130 void insert(const immed
& v
, int i
);
132 name_table
operator&(const name_table
&) const; // merge 2 name tables;
133 name_table
& operator&=(const name_table
&); // merge with other;
135 // reorders the table so element kind ordering matches historical ordering;
136 // sets ca so that new[ca[i]] = old[i];
137 // returns TRUE if table order is changed;
138 boolean
do_reorder_table(integer_row
&ca
);
140 // changes ntes occurring in both tables to sync their kinds;
141 static void change_name_types(name_table
& A
,
144 // are tables aligned and ordered?;
145 static boolean
is_aligned(const name_table
& A
,
146 const name_table
& B
);
148 // makes a table ret aligning elts of na and nb, reordered;
149 static name_table
* mk_align(const name_table
& na
, const name_table
& nb
);
151 // makes a table ret aligning elts of na and nb, reordered;
152 // and sets ca and cb;
153 // so that ret[ca[i]]==na[i] and ret[cb[i]]==nb[i];
154 static name_table
* align_tables(const name_table
&na
,
155 const name_table
&nb
,
156 integer_row
& ca
, integer_row
& cb
);
157 // aligns this with nb, reorders, and sets ca and cb so that;
158 // so that this[ca[i]]==oldthis[i] and this[cb[i]]==nb[i];
159 void align_with(const name_table
&nb
,
160 integer_row
& ca
, integer_row
& cb
);
162 constraint
lio_code_type() const;
164 base_symtab
* get_symtab(base_symtab
* in
= NULL
) const;
166 void print(FILE * fp
=stdout
) const;
167 void print_symtabs(FILE * fp
=stdout
) const;
171 enum print_exp_type
{ pet_single
, pet_system
, pet_system_nl
, pet_max
, pet_min
, pet_expr
, pet_expr_nl
};
173 /**************************************************************************
175 *** System of linear inequalities with names associated with ***
178 **************************************************************************/
179 class named_lin_ineq
{
180 friend class named_lin_ineq_list
;
186 named_lin_ineq() : lq(0, 1) { init(); }
187 named_lin_ineq(const named_lin_ineq
& c
) { init(); init(c
); }
188 named_lin_ineq(const named_lin_ineq
* c
) { init(); init(*c
); }
189 named_lin_ineq(const immed_list
& il
) { init(); init(il
); }
190 named_lin_ineq(int m
, int n
) : nt(n
),lq(m
, n
) { init(); }
191 named_lin_ineq(const name_table
&n
,
192 const lin_ineq
&l
) { init();
200 void init(const named_lin_ineq
& c
);
201 void init(int m
, int n
);
202 int init(const immed_list
& il
, int c
=0);
203 immed_list
* cvt_immed_list() const;
205 int uid() const { return unum
; }
207 name_table
& names() { return nt
; }
208 lin_ineq
& ineqs() { return lq
; }
210 const name_table
& const_names() const { return nt
; }
211 const lin_ineq
& const_ineqs() const { return lq
; }
214 int n() const { assert(nt
.n() == lq
.n());
216 int m() const { return lq
.m(); }
218 void swap_col(int i
, int j
);
219 void add_col(const name_table_entry
& nte
, int i
);
220 void del_col(int i
, int j
);
221 void del_col(int i
) { del_col(i
, i
); }
222 void del_col(const integer_row
&);
224 int find(const immed
& v
) const { return const_names().find(v
); }
227 void project_away(const immed
&, int *changed
=0);
228 void project_away(const name_table
&, int *changed
=0);
230 named_lin_ineq
& operator=(const named_lin_ineq
& c
);
231 named_lin_ineq
& operator=(const lin_ineq
& l
);
233 named_lin_ineq
operator&(const named_lin_ineq
& c
) const;
234 named_lin_ineq
& operator&=(const named_lin_ineq
& c
);
235 named_lin_ineq
& operator&=(const lin_ineq
& l
);
236 // treats 0 as TRUE; returns 0 if c1==c2==0;
237 // deletes or returns c{1,2} if del{1,2};
238 static named_lin_ineq
* and2(named_lin_ineq
* c1
,
242 boolean
operator==(const named_lin_ineq
& c2
) const;
243 boolean
operator>=(const named_lin_ineq
& c2
) const;
244 boolean
operator<=(const named_lin_ineq
& c2
) const
245 { return (c2
>= (*this)); };
246 boolean
operator~() const;
248 /* saman compatibility */
249 boolean
operator>>(const named_lin_ineq
& c2
) const
250 { return (*this >= c2
); };
251 boolean
operator<<(const named_lin_ineq
& c2
) const
252 { return (c2
>> (*this)); }
253 // aligns tables and reorders them;
254 void operator||(named_lin_ineq
& c
) { align_with(c
); };
255 /* end saman compatibility */
257 // a simple substitution method
258 // This is a cheap alternative to expensive Fourier-Motzkin
259 // substitution expression given in expr is of the form
260 //var >= sub_expr and var <= sub_expr or
262 named_lin_ineq
* substitute(const immed
& var
, const named_lin_ineq
& expr
)
264 void do_substitute(const immed
& var
, const named_lin_ineq
& expr
);
266 // do all sorts of fm-pairwise projection;
269 void cleanup(); // does simple cleanup;
270 // returns true for no-soln sys after cleanup();
271 boolean
is_clean_false() const;
272 void del_zero_cols();
274 void simplify(); // does somewhat more work to cleanup;
276 void print(FILE *fp
= stdout
) const;
277 void print_exp(print_exp_type tp
=pet_single
, FILE *fp
= stdout
) const;
279 instruction
* mk_bounds() const;
280 instruction
* create_expression(const immed
& v
,
282 block_symtab
* sym
=NULL
) const;
285 // NEED TO LINK LIBDEPENDENCE TO USE THIS FUNCTION
286 static named_lin_ineq
* mk_named_lin_ineq(array_info
& ai
,
289 // NEED TO LINK LIBDEPENDENCE TO USE THIS FUNCTION
290 static named_lin_ineq
* mk_named_lin_ineq(access_vector
& av
,
294 // reorders the table so element kind ordering matches historical ordering;
295 // if ca, then sets ca so that new[*ca[i]] = old[i];
296 void do_reorder_table(integer_row
*ca
=0);
298 // aligns tables and reorders them;
299 static void align_named_lin_ineqs(named_lin_ineq
& A
,
301 // aligns tables and reorders them;
302 void align_with(named_lin_ineq
&B
);
304 // aligns this table with nt; does not reorder;
305 void align(const name_table
& nt
);
307 // aligns tables, maximizing congruence of aux variables;
308 // may alter systems; returns number of auxes merged;
309 int merge_auxes(named_lin_ineq
&c2
);
311 static boolean
is_aligned(const named_lin_ineq
& A
,
312 const named_lin_ineq
& B
);
314 static named_lin_ineq
* merge_named_lin_ineqs(const named_lin_ineq
& A
,
315 const named_lin_ineq
& B
);
318 typedef named_lin_ineq
* p_named_lin_ineq
;
320 // NEED TO LINK LIBDEPENDENCE TO USE THIS FUNCTION
321 named_lin_ineq
* include_for(tree_for
* tf
,
322 named_lin_ineq
* c
= NULL
);